From 14521c7406ff0c8e3b42018df360ee2f14819094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Sun, 14 Jan 2018 19:13:34 -0800 Subject: [PATCH] Removed reliance on sinf/cosf CRT functions. --- include/bx/inline/math.inl | 10 ++++++ include/bx/math.h | 3 ++ src/math.cpp | 70 +++++++++++++++++++++++++++++++++----- tests/math_test.cpp | 17 ++++++++- 4 files changed, 91 insertions(+), 9 deletions(-) diff --git a/include/bx/inline/math.inl b/include/bx/inline/math.inl index 5167a40..710ff0b 100644 --- a/include/bx/inline/math.inl +++ b/include/bx/inline/math.inl @@ -122,6 +122,16 @@ namespace bx return _a * _a; } + inline float sin(float _a) + { + return cos(_a - kPiHalf); + } + + inline float pow(float _a, float _b) + { + return exp(_b * log(_a) ); + } + inline float exp2(float _a) { return pow(2.0f, _a); diff --git a/include/bx/math.h b/include/bx/math.h index 9b60134..834fbe9 100644 --- a/include/bx/math.h +++ b/include/bx/math.h @@ -125,6 +125,9 @@ namespace bx /// float pow(float _a, float _b); + /// + float exp(float _a); + /// float exp2(float _a); diff --git a/src/math.cpp b/src/math.cpp index d480dc7..7fe5a79 100644 --- a/src/math.cpp +++ b/src/math.cpp @@ -22,24 +22,78 @@ namespace bx const float kHuge = HUGE_VALF; #endif // BX_COMPILER_MSVC - float sin(float _a) - { - return ::sinf(_a); - } - float asin(float _a) { return ::asinf(_a); } + namespace + { + static const float kSinC2 = -0.16666667163372039794921875f; + static const float kSinC4 = 8.333347737789154052734375e-3f; + static const float kSinC6 = -1.9842604524455964565277099609375e-4f; + static const float kSinC8 = 2.760012648650445044040679931640625e-6f; + static const float kSinC10 = -2.50293279435709337121807038784027099609375e-8f; + + static const float kCosC2 = -0.5f; + static const float kCosC4 = 4.166664183139801025390625e-2f; + static const float kCosC6 = -1.388833043165504932403564453125e-3f; + static const float kCosC8 = 2.47562347794882953166961669921875e-5f; + static const float kCosC10 = -2.59630184018533327616751194000244140625e-7f; + + } // namespace + float cos(float _a) { - return ::cosf(_a); + const float scaled = _a * 2.0f*kInvPi; + const float real = floor(scaled); + const float xx = _a - real * kPiHalf; + const int32_t bits = int32_t(real) & 3; + + float c0, c2, c4, c6, c8, c10; + + if (bits == 0 + || bits == 2) + { + c0 = 1.0f; + c2 = kCosC2; + c4 = kCosC4; + c6 = kCosC6; + c8 = kCosC8; + c10 = kCosC10; + } + else + { + c0 = xx; + c2 = kSinC2; + c4 = kSinC4; + c6 = kSinC6; + c8 = kSinC8; + c10 = kSinC10; + } + + const float xsq = square(xx); + float result; + result = xsq * c10 + c8; + result = xsq * result + c6; + result = xsq * result + c4; + result = xsq * result + c2; + result = xsq * result + 1.0f; + result *= c0; + + return bits == 1 || bits == 2 + ? -result + : result + ; } float tan(float _a) { +#if 0 + return sin(_a) / cos(_a); +#else return ::tanf(_a); +#endif } float acos(float _a) @@ -52,9 +106,9 @@ namespace bx return ::atan2f(_y, _x); } - float pow(float _a, float _b) + float exp(float _a) { - return exp(_b * log(_a) ); + return ::expf(_a); } float log(float _a) diff --git a/tests/math_test.cpp b/tests/math_test.cpp index d029329..13a75b4 100644 --- a/tests/math_test.cpp +++ b/tests/math_test.cpp @@ -52,10 +52,25 @@ TEST_CASE("libm", "") REQUIRE(bx::equal( 0.89f, bx::fract( 13.89f), 0.000001f) ); REQUIRE(bx::equal(-0.89f, bx::fract(-13.89f), 0.000001f) ); - for (float xx = 0.0f; xx < 100.0f; xx += 0.1f) + for (float xx = -100.0f; xx < 100.0f; xx += 0.1f) { REQUIRE(bx::equal(bx::pow(1.389f, xx), ::pow(1.389f, xx), 0.00001f) ); } + + for (float xx = -100.0f; xx < 100.0f; xx += 0.1f) + { + REQUIRE(bx::equal(bx::sin(xx), ::sin(xx), 0.00001f) ); + } + + for (float xx = -100.0f; xx < 100.0f; xx += 0.1f) + { + REQUIRE(bx::equal(bx::cos(xx), ::cos(xx), 0.00001f) ); + } + + for (float xx = -100.0f; xx < 100.0f; xx += 0.1f) + { + REQUIRE(bx::equal(bx::tan(xx), ::tan(xx), 0.00001f) ); + } } TEST_CASE("ToBits", "")