dexter has submitted this change. ( 
https://gerrit.osmocom.org/c/libosmocore/+/30933 )

Change subject: uitils: add floored and euclidian modulo functions
......................................................................

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
---
M include/osmocom/core/utils.h
M tests/utils/utils_test.c
M tests/utils/utils_test.ok
3 files changed, 102 insertions(+), 0 deletions(-)

Approvals:
  fixeria: Looks good to me, approved
  pespin: Looks good to me, but someone else must approve
  Jenkins Builder: Verified



diff --git a/include/osmocom/core/utils.h b/include/osmocom/core/utils.h
index d0e2e9b..ee7cfa4 100644
--- a/include/osmocom/core/utils.h
+++ b/include/osmocom/core/utils.h
@@ -182,6 +182,18 @@

 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 9ddae65..0b7bfe4 100644
--- a/tests/utils/utils_test.c
+++ b/tests/utils/utils_test.c
@@ -766,6 +766,65 @@
        }
 }

+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 @@
        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 1409d81..3f453e9 100644
--- a/tests/utils/utils_test.ok
+++ b/tests/utils/utils_test.ok
@@ -354,6 +354,36 @@

 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

--
To view, visit https://gerrit.osmocom.org/c/libosmocore/+/30933
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: If61cd54f43643325c45f64531c57fe4c5802a9cf
Gerrit-Change-Number: 30933
Gerrit-PatchSet: 7
Gerrit-Owner: dexter <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: dexter <[email protected]>
Gerrit-Reviewer: fixeria <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>
Gerrit-CC: neels <[email protected]>
Gerrit-MessageType: merged

Reply via email to