diff options
author | Campbell Barton <ideasman42@gmail.com> | 2020-11-13 08:58:14 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2020-11-13 09:05:46 +0300 |
commit | ccf8df66fea3650b3d43ed079f9eec4cf35e99f6 (patch) | |
tree | b0fef6285945c04849aa8a0af6f3ab032c255181 | |
parent | 40b2ce5ea73b4b7235435aa2e2ef7dc7742084a0 (diff) |
BLI_math: add floor_power_of_10, ceil_power_of_10
Add utility functions to get the floor/ceiling of a float value
to the next power of 10.
-rw-r--r-- | source/blender/blenlib/BLI_math_base.h | 3 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_base.c | 36 | ||||
-rw-r--r-- | source/blender/blenlib/tests/BLI_math_base_test.cc | 18 |
3 files changed, 57 insertions, 0 deletions
diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h index d2bb60717ca..0ec65999006 100644 --- a/source/blender/blenlib/BLI_math_base.h +++ b/source/blender/blenlib/BLI_math_base.h @@ -219,6 +219,9 @@ MINLINE unsigned int round_db_to_uint_clamp(double a); int pow_i(int base, int exp); double double_round(double x, int ndigits); +float floor_power_of_10(float f); +float ceil_power_of_10(float f); + #ifdef BLI_MATH_GCC_WARN_PRAGMA # pragma GCC diagnostic pop #endif diff --git a/source/blender/blenlib/intern/math_base.c b/source/blender/blenlib/intern/math_base.c index 30267661ae7..2bf06371740 100644 --- a/source/blender/blenlib/intern/math_base.c +++ b/source/blender/blenlib/intern/math_base.c @@ -79,3 +79,39 @@ double double_round(double x, int ndigits) /* if computation resulted in overflow, raise OverflowError */ return z; } + +/** + * Floor to the nearest power of 10, e.g.: + * - 15.0 -> 10.0 + * - 0.015 -> 0.01 + * - 1.0 -> 1.0 + * + * \param f: Value to floor, must be over 0.0. + * \note If we wanted to support signed values we could if this becomes necessary. + */ +float floor_power_of_10(float f) +{ + BLI_assert(!(f < 0.0f)); + if (f != 0.0f) { + return 1.0f / (powf(10.0f, ceilf(log10f(1.0f / f)))); + } + return 0.0f; +} + +/** + * Ceiling to the nearest power of 10, e.g.: + * - 15.0 -> 100.0 + * - 0.015 -> 0.1 + * - 1.0 -> 1.0 + * + * \param f: Value to ceiling, must be over 0.0. + * \note If we wanted to support signed values we could if this becomes necessary. + */ +float ceil_power_of_10(float f) +{ + BLI_assert(!(f < 0.0f)); + if (f != 0.0f) { + return 1.0f / (powf(10.0f, floorf(log10f(1.0f / f)))); + } + return 0.0f; +} diff --git a/source/blender/blenlib/tests/BLI_math_base_test.cc b/source/blender/blenlib/tests/BLI_math_base_test.cc index dc20c75576d..d006a2eb59a 100644 --- a/source/blender/blenlib/tests/BLI_math_base_test.cc +++ b/source/blender/blenlib/tests/BLI_math_base_test.cc @@ -113,3 +113,21 @@ TEST(math_base, Log2CeilU) EXPECT_EQ(log2_ceil_u(9), 4); EXPECT_EQ(log2_ceil_u(123456), 17); } + +TEST(math_base, CeilPowerOf10) +{ + EXPECT_EQ(ceil_power_of_10(0), 0); + EXPECT_EQ(ceil_power_of_10(1), 1); + EXPECT_EQ(ceil_power_of_10(1e-6f), 1e-6f); + EXPECT_NEAR(ceil_power_of_10(100.1f), 1000.0f, 1e-4f); + EXPECT_NEAR(ceil_power_of_10(99.9f), 100.0f, 1e-4f); +} + +TEST(math_base, FloorPowerOf10) +{ + EXPECT_EQ(floor_power_of_10(0), 0); + EXPECT_EQ(floor_power_of_10(1), 1); + EXPECT_EQ(floor_power_of_10(1e-6f), 1e-6f); + EXPECT_NEAR(floor_power_of_10(100.1f), 100.0f, 1e-4f); + EXPECT_NEAR(floor_power_of_10(99.9f), 10.0f, 1e-4f); +} |