diff --git a/include/bx/inline/math.inl b/include/bx/inline/math.inl index 81ce759..72e4ef2 100644 --- a/include/bx/inline/math.inl +++ b/include/bx/inline/math.inl @@ -10,6 +10,7 @@ #endif // BX_MATH_H_HEADER_GUARD #include +#include namespace bx { @@ -191,11 +192,18 @@ namespace bx return pow(2.0f, _a); } + template<> inline BX_CONST_FUNC float log2(float _a) { return log(_a) * kInvLogNat2; } + template<> + inline BX_CONST_FUNC int32_t log2(int32_t _a) + { + return 31 - uint32_cntlz(_a); + } + inline BX_CONST_FUNC float rsqrtRef(float _a) { return pow(_a, -0.5f); diff --git a/include/bx/math.h b/include/bx/math.h index 6e28839..a46ab0d 100644 --- a/include/bx/math.h +++ b/include/bx/math.h @@ -225,7 +225,8 @@ namespace bx /// Returns the base 2 logarithm of _a. /// - BX_CONST_FUNC float log2(float _a); + template + BX_CONST_FUNC Ty log2(Ty _a); /// Returns the square root of _a. /// diff --git a/tests/math_test.cpp b/tests/math_test.cpp index 84bec2c..00a73b2 100644 --- a/tests/math_test.cpp +++ b/tests/math_test.cpp @@ -31,6 +31,33 @@ TEST_CASE("log2", "") { log2_test(0.0f); log2_test(256.0f); + + REQUIRE(0.0f == bx::log2(1.0f) ); + REQUIRE(0 == bx::log2(1) ); + + REQUIRE(1.0f == bx::log2(2.0f) ); + REQUIRE(1 == bx::log2(2) ); + + REQUIRE(2.0f == bx::log2(4.0f) ); + REQUIRE(2 == bx::log2(4) ); + + REQUIRE(3.0f == bx::log2(8.0f) ); + REQUIRE(3 == bx::log2(8) ); + + REQUIRE(4.0f == bx::log2(16.0f) ); + REQUIRE(4 == bx::log2(16) ); + + REQUIRE(5.0f == bx::log2(32.0f) ); + REQUIRE(5 == bx::log2(32) ); + + REQUIRE(6.0f == bx::log2(64.0f) ); + REQUIRE(6 == bx::log2(64) ); + + REQUIRE(7.0f == bx::log2(128.0f) ); + REQUIRE(7 == bx::log2(128) ); + + REQUIRE(8.0f == bx::log2(256.0f) ); + REQUIRE(8 == bx::log2(256) ); } TEST_CASE("libm", "")