include: util: Add DIV_ROUND_CLOSEST helper
It's similar to DIV_ROUND_UP, but rounds to the nearest integer. Some basic unit tests were introduced to check that it works as intended. Signed-off-by: Kornel Dulęba <mindal@semihalf.com>
This commit is contained in:
parent
ecbaac60bd
commit
8fc913374f
3 changed files with 42 additions and 0 deletions
|
@ -259,6 +259,25 @@ extern "C" {
|
|||
*/
|
||||
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
|
||||
|
||||
/**
|
||||
* @brief Divide and round to the nearest integer.
|
||||
*
|
||||
* Example:
|
||||
* @code{.c}
|
||||
* DIV_ROUND_CLOSEST(5, 2); // 3
|
||||
* DIV_ROUND_CLOSEST(5, -2); // -3
|
||||
* DIV_ROUND_CLOSEST(5, 3); // 2
|
||||
* @endcode
|
||||
*
|
||||
* @param n Numerator.
|
||||
* @param d Denominator.
|
||||
*
|
||||
* @return The result of @p n / @p d, rounded to the nearest integer.
|
||||
*/
|
||||
#define DIV_ROUND_CLOSEST(n, d) \
|
||||
((((n) < 0) ^ ((d) < 0)) ? ((n) - ((d) / 2)) / (d) : \
|
||||
((n) + ((d) / 2)) / (d))
|
||||
|
||||
/**
|
||||
* @brief Ceiling function applied to @p numerator / @p divider as a fraction.
|
||||
* @deprecated Use DIV_ROUND_UP() instead.
|
||||
|
|
|
@ -151,6 +151,11 @@ ZTEST(util_cxx, test_DIV_ROUND_UP)
|
|||
run_DIV_ROUND_UP();
|
||||
}
|
||||
|
||||
ZTEST(util_cxx, test_DIV_ROUND_CLOSEST)
|
||||
{
|
||||
run_DIV_ROUND_CLOSEST();
|
||||
}
|
||||
|
||||
ZTEST_SUITE(util_cxx, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
#if __cplusplus
|
||||
|
@ -294,4 +299,9 @@ ZTEST(util_cc, test_DIV_ROUND_UP)
|
|||
run_DIV_ROUND_UP();
|
||||
}
|
||||
|
||||
ZTEST(util_cc, test_DIV_ROUND_CLOSEST)
|
||||
{
|
||||
run_DIV_ROUND_CLOSEST();
|
||||
}
|
||||
|
||||
ZTEST_SUITE(util_cc, NULL, NULL, NULL, NULL, NULL);
|
||||
|
|
|
@ -615,3 +615,16 @@ void run_DIV_ROUND_UP(void)
|
|||
zassert_equal(DIV_ROUND_UP(1, 2), 1);
|
||||
zassert_equal(DIV_ROUND_UP(3, 2), 2);
|
||||
}
|
||||
|
||||
void run_DIV_ROUND_CLOSEST(void)
|
||||
{
|
||||
zassert_equal(DIV_ROUND_CLOSEST(0, 1), 0);
|
||||
/* 5 / 2 = 2.5 -> 3 */
|
||||
zassert_equal(DIV_ROUND_CLOSEST(5, 2), 3);
|
||||
zassert_equal(DIV_ROUND_CLOSEST(5, -2), -3);
|
||||
zassert_equal(DIV_ROUND_CLOSEST(-5, 2), -3);
|
||||
zassert_equal(DIV_ROUND_CLOSEST(-5, -2), 3);
|
||||
/* 7 / 3 = 2.(3) -> 2 */
|
||||
zassert_equal(DIV_ROUND_CLOSEST(7, 3), 2);
|
||||
zassert_equal(DIV_ROUND_CLOSEST(-7, 3), -2);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue