diff --git a/include/bw_math.h b/include/bw_math.h index 34fd862..eda5ab9 100644 --- a/include/bw_math.h +++ b/include/bw_math.h @@ -369,8 +369,11 @@ static inline float bw_log10f(float x); * ```>>> */ static inline float bw_pow2f(float x); /*! <<<``` - * Returns an approximation of 2 raised to the power of `x`. - * + * Returns an approximation of 2 raised to the power of `x`. For `x < -126.f` + * it just returns `0.f`. + * + * `x` must be less than or equal to `127.999f`. + * * Relative error < 0.062%. * * #### bw_expf() @@ -378,15 +381,21 @@ static inline float bw_pow2f(float x); static inline float bw_expf(float x); /*! <<<``` * Returns an approximation of e (Euler's number) raised to the power of `x`. - * + * For `x < -87.3365447505531f` it just returns `0`. + * + * `x` must be less than or equal to `88.722f`. + * * Relative error < 0.062%. * * #### bw_pow10f() * ```>>> */ static inline float bw_pow10f(float x); /*! <<<``` - * Returns an approximation of 10 raised to the power of `x`. - * + * Returns an approximation of 10 raised to the power of `x`. For + * `x < -37.92977945366162f` it just returns `0`. + * + * `x` must be less than or equal to `38.531f`. + * * Relative error < 0.062%. * * #### bw_dB2linf() @@ -725,7 +734,7 @@ static inline float bw_log10f(float x) { } static inline float bw_pow2f(float x) { - BW_ASSERT(bw_is_finite(x)); + BW_ASSERT(!bw_is_nan(x)); BW_ASSERT(x <= 127.999f); if (x < -126.f) return 0.f; @@ -741,7 +750,7 @@ static inline float bw_pow2f(float x) { } static inline float bw_expf(float x) { - BW_ASSERT(bw_is_finite(x)); + BW_ASSERT(!bw_is_nan(x)); BW_ASSERT(x <= 88.722f); const float y = bw_pow2f(1.442695040888963f * x); BW_ASSERT(bw_is_finite(y)); @@ -749,7 +758,7 @@ static inline float bw_expf(float x) { } static inline float bw_pow10f(float x) { - BW_ASSERT(bw_is_finite(x)); + BW_ASSERT(!bw_is_nan(x)); BW_ASSERT(x <= 38.531f); const float y = bw_pow2f(3.321928094887363f * x); BW_ASSERT(bw_is_finite(y)); diff --git a/test/bw_math.c b/test/bw_math.c index 32d1795..197ce4b 100644 --- a/test/bw_math.c +++ b/test/bw_math.c @@ -909,6 +909,74 @@ int main() { TEST_ABS_REL(bw_log10f(4.832930238571732e+23f), 2.368421052631579e+01f, 0.0017f, 0.012f); TEST_ABS_REL(bw_log10f(6.951927961775592e+26f), 2.684210526315789e+01f, 0.0017f, 0.012f); TEST_ABS_REL(bw_log10f(1e+30f), 3.000000000000000e+01f, 0.0017f, 0.012f); + + TEST(bw_pow2f(-INFINITY), 0.f); + TEST(bw_pow2f(-127.f), 0.f); + TEST_REL(bw_pow2f(-120.5f), 5.319680170962675e-37f, 0.00062f); + TEST_REL(bw_pow2f(-100.5f), 5.578088954947358e-31f, 0.00062f); + TEST_REL(bw_pow2f(-80.5f), 5.849050204022881e-25f, 0.00062f); + TEST_REL(bw_pow2f(-60.5f), 6.133173666733497e-19f, 0.00062f); + TEST_REL(bw_pow2f(-40.5f), 6.431098710768743e-13f, 0.00062f); + TEST_REL(bw_pow2f(-20.5f), 6.743495761743046e-07f, 0.00062f); + TEST_REL(bw_pow2f(0.f), 1.f, 0.00062f); + TEST_REL(bw_pow2f(0.1f), 1.071773462536293f, 0.00062f); + TEST_REL(bw_pow2f(0.2f), 1.148698354997035f, 0.00062f); + TEST_REL(bw_pow2f(0.3f), 1.231144413344916f, 0.00062f); + TEST_REL(bw_pow2f(0.4f), 1.319507910772894f, 0.00062f); + TEST_REL(bw_pow2f(0.5f), 1.414213562373095f, 0.00062f); + TEST_REL(bw_pow2f(0.6f), 1.515716566510398f, 0.00062f); + TEST_REL(bw_pow2f(0.7f), 1.624504792712471f, 0.00062f); + TEST_REL(bw_pow2f(0.8f), 1.741101126592248f, 0.00062f); + TEST_REL(bw_pow2f(0.9f), 1.866065983073615f, 0.00062f); + TEST_REL(bw_pow2f(1.f), 2.f, 0.00062f); + TEST_REL(bw_pow2f(20.5f), 1482910.400378931f, 0.00062f); + TEST_REL(bw_pow2f(40.5f), 1554944255987.738f, 0.00062f); + TEST_REL(bw_pow2f(60.5f), 1.630477228166598e+18f, 0.00062f); + TEST_REL(bw_pow2f(80.5f), 1.709679290002019e+24f, 0.00062f); + TEST_REL(bw_pow2f(100.5f), 1.792728671193157e+30f, 0.00062f); + TEST_REL(bw_pow2f(120.5f), 1.879812259125035e+36f, 0.00062f); + + TEST(bw_expf(-INFINITY), 0.f); + TEST(bw_expf(-88.f), 0.f); + TEST_REL(bw_expf(-80.5f), 1.094697702953142e-35f, 0.00062f); + TEST_REL(bw_expf(-60.5f), 5.311092249679095e-27f, 0.00062f); + TEST_REL(bw_expf(-40.5f), 2.576757109154981e-18f, 0.00062f); + TEST_REL(bw_expf(-20.5f), 1.250152866386743e-09f, 0.00062f); + TEST_REL(bw_expf(0.f), 1.f, 0.00062f); + TEST_REL(bw_expf(0.1f), 1.105170918075648f, 0.00062f); + TEST_REL(bw_expf(0.2f), 1.221402758160170f, 0.00062f); + TEST_REL(bw_expf(0.3f), 1.349858807576003f, 0.00062f); + TEST_REL(bw_expf(0.4f), 1.491824697641270f, 0.00062f); + TEST_REL(bw_expf(0.5f), 1.648721270700128f, 0.00062f); + TEST_REL(bw_expf(0.6f), 1.822118800390509f, 0.00062f); + TEST_REL(bw_expf(0.7f), 2.013752707470477f, 0.00062f); + TEST_REL(bw_expf(0.8f), 2.225540928492468f, 0.00062f); + TEST_REL(bw_expf(0.9f), 2.459603111156950f, 0.00062f); + TEST_REL(bw_expf(1.f), 2.718281828459045f, 0.00062f); + TEST_REL(bw_expf(20.5f), 799902177.4755054f, 0.00062f); + TEST_REL(bw_expf(40.5f), 3.880846962436204e+17f, 0.00062f); + TEST_REL(bw_expf(60.5f), 1.882851874885851e+26f, 0.00062f); + TEST_REL(bw_expf(80.5f), 9.134941978066843e+34f, 0.00062f); + + TEST(bw_pow10f(-INFINITY), 0.f); + TEST(bw_pow10f(-38.f), 0.f); + TEST_REL(bw_pow10f(-30.5f), 3.162277660168379e-31f, 0.00062f); + TEST_REL(bw_pow10f(-20.5f), 3.162277660168379e-21f, 0.00062f); + TEST_REL(bw_pow10f(-10.5f), 3.162277660168379e-11f, 0.00062f); + TEST_REL(bw_pow10f(0.f), 1.f, 0.00062f); + TEST_REL(bw_pow10f(0.1f), 1.258925411794167e+00f, 0.00062f); + TEST_REL(bw_pow10f(0.2f), 1.584893192461114e+00f, 0.00062f); + TEST_REL(bw_pow10f(0.3f), 1.995262314968880e+00f, 0.00062f); + TEST_REL(bw_pow10f(0.4f), 2.511886431509580e+00f, 0.00062f); + TEST_REL(bw_pow10f(0.5f), 3.162277660168380e+00f, 0.00062f); + TEST_REL(bw_pow10f(0.6f), 3.981071705534972e+00f, 0.00062f); + TEST_REL(bw_pow10f(0.7f), 5.011872336272722e+00f, 0.00062f); + TEST_REL(bw_pow10f(0.8f), 6.309573444801933e+00f, 0.00062f); + TEST_REL(bw_pow10f(0.9f), 7.943282347242816e+00f, 0.00062f); + TEST_REL(bw_pow10f(1.f), 10.f, 0.00062f); + TEST_REL(bw_pow10f(10.5f), 31622776601.68379f, 0.00062f); + TEST_REL(bw_pow10f(20.5f), 3.162277660168379e+20f, 0.00062f); + TEST_REL(bw_pow10f(30.5f), 3.162277660168380e+30f, 0.00062f); printf("\nsuceeded: %d, failed: %d\n\n", n_ok, n_ko);