diff options
author | Philipp Maier <pmaier@sysmocom.de> | 2023-01-11 10:55:47 +0100 |
---|---|---|
committer | dexter <pmaier@sysmocom.de> | 2023-01-12 09:33:07 +0000 |
commit | 94705d042a94d40585414d83d446889a087dae05 (patch) | |
tree | 0f4d349a86793b9e7facb4376bb00c18a57c03ff | |
parent | e709bd4814020146baff2538ea50dbbc96432ff0 (diff) |
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
-rw-r--r-- | include/osmocom/core/utils.h | 12 | ||||
-rw-r--r-- | tests/utils/utils_test.c | 60 | ||||
-rw-r--r-- | tests/utils/utils_test.ok | 30 |
3 files changed, 102 insertions, 0 deletions
diff --git a/include/osmocom/core/utils.h b/include/osmocom/core/utils.h index d0e2e9bf..ee7cfa49 100644 --- a/include/osmocom/core/utils.h +++ b/include/osmocom/core/utils.h @@ -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. */ diff --git a/tests/utils/utils_test.c b/tests/utils/utils_test.c index 9ddae651..0b7bfe44 100644 --- a/tests/utils/utils_test.c +++ b/tests/utils/utils_test.c @@ -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(); diff --git a/tests/utils/utils_test.ok b/tests/utils/utils_test.ok index 1409d81a..3f453e95 100644 --- a/tests/utils/utils_test.ok +++ b/tests/utils/utils_test.ok @@ -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 |