From 228d8e72c0f416bc6121fdfce71b318522f619a5 Mon Sep 17 00:00:00 2001 From: Karl Fessel Date: Wed, 9 Nov 2022 17:46:49 +0100 Subject: [PATCH 1/2] unittest/core-macros: add negtive cases for DIV_ROUND and DIV_ROUND_UP --- .../unittests/tests-core/tests-core-macros.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/unittests/tests-core/tests-core-macros.c b/tests/unittests/tests-core/tests-core-macros.c index 15644d71821b..3070db2eaf20 100644 --- a/tests/unittests/tests-core/tests-core-macros.c +++ b/tests/unittests/tests-core/tests-core-macros.c @@ -27,7 +27,17 @@ static void test_math_div_round(void) TEST_ASSERT_EQUAL_INT(3, DIV_ROUND(a, 7)); TEST_ASSERT_EQUAL_INT(3, DIV_ROUND(21, 7)); TEST_ASSERT_EQUAL_INT(3, DIV_ROUND(22, 7)); + TEST_ASSERT_EQUAL_INT(3, DIV_ROUND(-20, -7)); + TEST_ASSERT_EQUAL_INT(3, DIV_ROUND(-21, -7)); + TEST_ASSERT_EQUAL_INT(3, DIV_ROUND(-22, -7)); + TEST_ASSERT_EQUAL_INT(-3, DIV_ROUND(20, -7)); + TEST_ASSERT_EQUAL_INT(-3, DIV_ROUND(21, -7)); + TEST_ASSERT_EQUAL_INT(-3, DIV_ROUND(22, -7)); + TEST_ASSERT_EQUAL_INT(-3, DIV_ROUND(-20, 7)); + TEST_ASSERT_EQUAL_INT(-3, DIV_ROUND(-21, 7)); + TEST_ASSERT_EQUAL_INT(-3, DIV_ROUND(-22, 7)); TEST_ASSERT_EQUAL_INT(0, DIV_ROUND(1, UINT32_MAX)); + } static void test_math_div_round_up(void) @@ -35,6 +45,15 @@ static void test_math_div_round_up(void) TEST_ASSERT_EQUAL_INT(3, DIV_ROUND_UP(20, 7)); TEST_ASSERT_EQUAL_INT(3, DIV_ROUND_UP(21, 7)); TEST_ASSERT_EQUAL_INT(4, DIV_ROUND_UP(22, 7)); + TEST_ASSERT_EQUAL_INT(3, DIV_ROUND_UP(-20, -7)); + TEST_ASSERT_EQUAL_INT(3, DIV_ROUND_UP(-21, -7)); + TEST_ASSERT_EQUAL_INT(4, DIV_ROUND_UP(-22, -7)); + TEST_ASSERT_EQUAL_INT(-2, DIV_ROUND_UP(20, -7)); + TEST_ASSERT_EQUAL_INT(-3, DIV_ROUND_UP(21, -7)); + TEST_ASSERT_EQUAL_INT(-3, DIV_ROUND_UP(22, -7)); + TEST_ASSERT_EQUAL_INT(-2, DIV_ROUND_UP(-20, 7)); + TEST_ASSERT_EQUAL_INT(-3, DIV_ROUND_UP(-21, 7)); + TEST_ASSERT_EQUAL_INT(-3, DIV_ROUND_UP(-22, 7)); TEST_ASSERT_EQUAL_INT(1, DIV_ROUND_UP(1, UINT32_MAX)); TEST_ASSERT_EQUAL_INT(1536, MATH_ALIGN(1514, 64)); From aa31dd7d669fa03b29f509b871bc117f5bf61dc5 Mon Sep 17 00:00:00 2001 From: Karl Fessel Date: Wed, 9 Nov 2022 17:50:01 +0100 Subject: [PATCH 2/2] core/macros: rewrite DIV_ROUND, DIV_ROUND_UP; add DIV_ROUND_INF --- core/include/macros/math.h | 17 +++++++++----- .../unittests/tests-core/tests-core-macros.c | 23 +++++++++++++++++-- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/core/include/macros/math.h b/core/include/macros/math.h index 92b987d58cb8..cf7c3744450f 100644 --- a/core/include/macros/math.h +++ b/core/include/macros/math.h @@ -33,20 +33,25 @@ extern "C" { unsigned long long: 1, \ default: ((a) <= 0 ? ((a) == 0 ? 1L : -1L ): 1L)) /** - * @brief Calculates @p a/ @p b with arithmetic rounding + * @brief Calculates @p a/ @p b with arithmetic rounding (.5 away from zero) */ -#define DIV_ROUND(a, b) (((a) + SIGNOF(a) * (b) / 2) / (b)) +#define DIV_ROUND(a, b) ((SIGNOF(a) * ((SIGNOF(a) * (a)) + (SIGNOF(b) * (b)) / 2) / (b))) /** - * @brief Calculates @p a/ @p b, always rounding up to the - * next whole number + * @brief Calculates @p a/ @p b, always rounding up (towards positive infinity) */ -#define DIV_ROUND_UP(a, b) (((a) + SIGNOF(a) * ((b) - SIGNOF(b))) / (b)) +#define DIV_ROUND_UP(a, b) ((SIGNOF(a)>0 && SIGNOF(b)>0) ? (((a) + (b) - 1) / (b)):\ + (SIGNOF(a)<0 && SIGNOF(b)<0) ? (((a) + (b) + 1) / (b)): (a) / (b)) + +/** + * @brief Calculates @p a/ @p b, always rounding away from zero (towards positive and negative inf) + */ +#define DIV_ROUND_INF(a, b) (SIGNOF(a) * (((SIGNOF(a) * (a)) + (SIGNOF(b) * (b)) - 1) / (b))) /** * @brief Align @p num with the next multiple of @p chunk */ -#define MATH_ALIGN(num, chunk) ((chunk) * DIV_ROUND_UP(num, chunk)) +#define MATH_ALIGN(num, chunk) ((chunk) * DIV_ROUND_INF(num, chunk)) #ifdef __cplusplus } diff --git a/tests/unittests/tests-core/tests-core-macros.c b/tests/unittests/tests-core/tests-core-macros.c index 3070db2eaf20..1170d6b9b8be 100644 --- a/tests/unittests/tests-core/tests-core-macros.c +++ b/tests/unittests/tests-core/tests-core-macros.c @@ -36,7 +36,7 @@ static void test_math_div_round(void) TEST_ASSERT_EQUAL_INT(-3, DIV_ROUND(-20, 7)); TEST_ASSERT_EQUAL_INT(-3, DIV_ROUND(-21, 7)); TEST_ASSERT_EQUAL_INT(-3, DIV_ROUND(-22, 7)); - TEST_ASSERT_EQUAL_INT(0, DIV_ROUND(1, UINT32_MAX)); + TEST_ASSERT_EQUAL_INT(0, DIV_ROUND(1, (long long) UINT32_MAX)); } @@ -54,7 +54,25 @@ static void test_math_div_round_up(void) TEST_ASSERT_EQUAL_INT(-2, DIV_ROUND_UP(-20, 7)); TEST_ASSERT_EQUAL_INT(-3, DIV_ROUND_UP(-21, 7)); TEST_ASSERT_EQUAL_INT(-3, DIV_ROUND_UP(-22, 7)); - TEST_ASSERT_EQUAL_INT(1, DIV_ROUND_UP(1, UINT32_MAX)); + TEST_ASSERT_EQUAL_INT(1, DIV_ROUND_UP(1, (long long) UINT32_MAX)); +} + +static void test_math_div_round_inf(void) +{ + TEST_ASSERT_EQUAL_INT(3, DIV_ROUND_INF(20, 7)); + TEST_ASSERT_EQUAL_INT(3, DIV_ROUND_INF(21, 7)); + TEST_ASSERT_EQUAL_INT(4, DIV_ROUND_INF(22, 7)); + TEST_ASSERT_EQUAL_INT(3, DIV_ROUND_INF(-20, -7)); + TEST_ASSERT_EQUAL_INT(3, DIV_ROUND_INF(-21, -7)); + TEST_ASSERT_EQUAL_INT(4, DIV_ROUND_INF(-22, -7)); + TEST_ASSERT_EQUAL_INT(-3, DIV_ROUND_INF(20, -7)); + TEST_ASSERT_EQUAL_INT(-3, DIV_ROUND_INF(21, -7)); + TEST_ASSERT_EQUAL_INT(-4, DIV_ROUND_INF(22, -7)); + TEST_ASSERT_EQUAL_INT(-3, DIV_ROUND_INF(-20, 7)); + TEST_ASSERT_EQUAL_INT(-3, DIV_ROUND_INF(-21, 7)); + TEST_ASSERT_EQUAL_INT(-4, DIV_ROUND_INF(-22, 7)); + TEST_ASSERT_EQUAL_INT(1, DIV_ROUND_INF(1, UINT32_MAX)); + TEST_ASSERT_EQUAL_INT(-1, DIV_ROUND_INF(1, (long long) INT32_MIN)); TEST_ASSERT_EQUAL_INT(1536, MATH_ALIGN(1514, 64)); } @@ -65,6 +83,7 @@ Test *tests_core_macros_tests(void) new_TestFixture(test_math_signof), new_TestFixture(test_math_div_round), new_TestFixture(test_math_div_round_up), + new_TestFixture(test_math_div_round_inf), }; EMB_UNIT_TESTCALLER(core_macros_tests, NULL, NULL, fixtures);