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))
|
#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.
|
* @brief Ceiling function applied to @p numerator / @p divider as a fraction.
|
||||||
* @deprecated Use DIV_ROUND_UP() instead.
|
* @deprecated Use DIV_ROUND_UP() instead.
|
||||||
|
|
|
@ -151,6 +151,11 @@ ZTEST(util_cxx, test_DIV_ROUND_UP)
|
||||||
run_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);
|
ZTEST_SUITE(util_cxx, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
|
@ -294,4 +299,9 @@ ZTEST(util_cc, test_DIV_ROUND_UP)
|
||||||
run_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);
|
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(1, 2), 1);
|
||||||
zassert_equal(DIV_ROUND_UP(3, 2), 2);
|
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