Skip to content

Commit

Permalink
Merge pull request #18858 from kfessel/p-fix-DIV2
Browse files Browse the repository at this point in the history
core/marco: fix DIV_ROUND
  • Loading branch information
kfessel authored Nov 10, 2022
2 parents a17ae05 + aa31dd7 commit 19021d6
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 8 deletions.
17 changes: 11 additions & 6 deletions core/include/macros/math.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
42 changes: 40 additions & 2 deletions tests/unittests/tests-core/tests-core-macros.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,52 @@ 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(0, DIV_ROUND(1, UINT32_MAX));
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, (long long) UINT32_MAX));

}

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(1, DIV_ROUND_UP(1, UINT32_MAX));
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, (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));
}
Expand All @@ -46,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);
Expand Down

0 comments on commit 19021d6

Please sign in to comment.