mirror of https://gerrit.osmocom.org/libosmocore
uitils: add floored and euclidian modulo functions
C/C++ only implements a so called "truncated modulo" function. Lets also add a floored and an euclidian modulo function to be more complete. The functions will be used to generalize the following Change: I5fb2b0ada8d409730ac22963741fb4ab0026abdd Change-Id: If61cd54f43643325c45f64531c57fe4c5802a9cf
This commit is contained in:
parent
e709bd4814
commit
94705d042a
|
@ -182,6 +182,18 @@ int osmo_print_n(char *buf, size_t bufsize, const char *str, size_t n);
|
|||
|
||||
uint32_t osmo_isqrt32(uint32_t x);
|
||||
|
||||
/*! Floored Modulo (See also: Daan Leijen, Division and Modulus for Computer Scientists).
|
||||
* \param[in] x dividend.
|
||||
* \param[in] y divisor.
|
||||
* \returns remainder of x divided by y. */
|
||||
#define OSMO_MOD_FLR(x, y) (((x) > 0 && (y) < 0) || ((x) < 0 && (y) > 0) ? (x) % (y) + (y) : (x) % (y))
|
||||
|
||||
/*! Euclidean Modulo (See also: Daan Leijen, Division and Modulus for Computer Scientists).
|
||||
* \param[in] x dividend.
|
||||
* \param[in] y divisor.
|
||||
* \returns remainder of x divided by y. */
|
||||
#define OSMO_MOD_EUC(x, y) ((x) % (y) < 0 ? (y) > 0 ? (x) % (y) + (y) : (x) % (y) - (y) : (x) % (y))
|
||||
|
||||
char osmo_luhn(const char* in, int in_len);
|
||||
|
||||
/*! State for OSMO_STRBUF_APPEND() and OSMO_STRBUF_PRINTF(). See there for examples. */
|
||||
|
|
|
@ -766,6 +766,65 @@ static void isqrt_test(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void mod_test_mod(int x, int y, int expected_result)
|
||||
{
|
||||
int result;
|
||||
result = x % y;
|
||||
printf(" %d mod %d = %d = %d\n", x, y, result, expected_result);
|
||||
OSMO_ASSERT(result == expected_result);
|
||||
}
|
||||
|
||||
static void mod_test_mod_flr(int x, int y, int expected_result)
|
||||
{
|
||||
int result;
|
||||
result = OSMO_MOD_FLR(x, y);
|
||||
printf(" %d mod_flr %d = %d = %d\n", x, y, result, expected_result);
|
||||
OSMO_ASSERT(result == expected_result);
|
||||
}
|
||||
|
||||
static void mod_test_mod_euc(int x, int y, int expected_result)
|
||||
{
|
||||
int result;
|
||||
result = OSMO_MOD_EUC(x, y);
|
||||
printf(" %d mod_euc %d = %d = %d\n", x, y, result, expected_result);
|
||||
OSMO_ASSERT(result == expected_result);
|
||||
}
|
||||
|
||||
static void mod_test(void)
|
||||
{
|
||||
/* See also: Daan Leijen, Division and Modulus for Computer
|
||||
* Scientists, section 1.3 */
|
||||
|
||||
printf("\nTesting built in truncated modulo for comparison:\n");
|
||||
mod_test_mod(8, 3, 2);
|
||||
mod_test_mod(8, -3, 2);
|
||||
mod_test_mod(-8, 3, -2);
|
||||
mod_test_mod(-8, -3, -2);
|
||||
mod_test_mod(1, 2, 1);
|
||||
mod_test_mod(1, -2, 1);
|
||||
mod_test_mod(-1, 2, -1);
|
||||
mod_test_mod(-1, -2, -1);
|
||||
|
||||
printf("\nTesting OSMO_MOD_FLR():\n");
|
||||
mod_test_mod_flr(8, 3, 2);
|
||||
mod_test_mod_flr(8, -3, -1);
|
||||
mod_test_mod_flr(-8, 3, 1);
|
||||
mod_test_mod_flr(-8, -3, -2);
|
||||
mod_test_mod_flr(1, 2, 1);
|
||||
mod_test_mod_flr(1, -2, -1);
|
||||
mod_test_mod_flr(-1, 2, 1);
|
||||
mod_test_mod_flr(-1, -2, -1);
|
||||
|
||||
printf("\nTesting OSMO_MOD_EUC():\n");
|
||||
mod_test_mod_euc(8, 3, 2);
|
||||
mod_test_mod_euc(8, -3, 2);
|
||||
mod_test_mod_euc(-8, 3, 1);
|
||||
mod_test_mod_euc(-8, -3, 1);
|
||||
mod_test_mod_euc(1, 2, 1);
|
||||
mod_test_mod_euc(1, -2, 1);
|
||||
mod_test_mod_euc(-1, 2, 1);
|
||||
mod_test_mod_euc(-1, -2, 1);
|
||||
}
|
||||
|
||||
struct osmo_sockaddr_to_str_and_uint_test_case {
|
||||
uint16_t port;
|
||||
|
@ -2088,6 +2147,7 @@ int main(int argc, char **argv)
|
|||
str_escape3_test();
|
||||
str_quote3_test();
|
||||
isqrt_test();
|
||||
mod_test();
|
||||
osmo_sockaddr_to_str_and_uint_test();
|
||||
osmo_str_tolowupper_test();
|
||||
strbuf_test();
|
||||
|
|
|
@ -354,6 +354,36 @@ strcmp("NULL", osmo_quote_cstr_c(ctx, NULL, -1)) == 0
|
|||
|
||||
Testing integer square-root
|
||||
|
||||
Testing built in truncated modulo for comparison:
|
||||
8 mod 3 = 2 = 2
|
||||
8 mod -3 = 2 = 2
|
||||
-8 mod 3 = -2 = -2
|
||||
-8 mod -3 = -2 = -2
|
||||
1 mod 2 = 1 = 1
|
||||
1 mod -2 = 1 = 1
|
||||
-1 mod 2 = -1 = -1
|
||||
-1 mod -2 = -1 = -1
|
||||
|
||||
Testing OSMO_MOD_FLR():
|
||||
8 mod_flr 3 = 2 = 2
|
||||
8 mod_flr -3 = -1 = -1
|
||||
-8 mod_flr 3 = 1 = 1
|
||||
-8 mod_flr -3 = -2 = -2
|
||||
1 mod_flr 2 = 1 = 1
|
||||
1 mod_flr -2 = -1 = -1
|
||||
-1 mod_flr 2 = 1 = 1
|
||||
-1 mod_flr -2 = -1 = -1
|
||||
|
||||
Testing OSMO_MOD_EUC():
|
||||
8 mod_euc 3 = 2 = 2
|
||||
8 mod_euc -3 = 2 = 2
|
||||
-8 mod_euc 3 = 1 = 1
|
||||
-8 mod_euc -3 = 1 = 1
|
||||
1 mod_euc 2 = 1 = 1
|
||||
1 mod_euc -2 = 1 = 1
|
||||
-1 mod_euc 2 = 1 = 1
|
||||
-1 mod_euc -2 = 1 = 1
|
||||
|
||||
osmo_sockaddr_to_str_and_uint_test
|
||||
[0] [0.0.0.0]:0 addr_len=20 --> [0.0.0.0]:0 rc=7
|
||||
[1] [255.255.255.255]:65535 addr_len=20 --> [255.255.255.255]:65535 rc=15
|
||||
|
|
Loading…
Reference in New Issue