more bw_math doc improvements + more tests

This commit is contained in:
Stefano D'Angelo 2023-08-10 16:17:45 +02:00
parent 6e2f5b1bce
commit 0da7b31504
2 changed files with 100 additions and 29 deletions

View File

@ -263,8 +263,7 @@ static inline float bw_rcpf(float x);
/*! <<<```
* Returns the reciprocal of `x` (i.e., `1.f / x`).
*
* Not guaranteed to work for `x` having exponent too big or too small. Safe
* range: |`x`| in [2^-90, 2^90].
* |`x`| must be in [2^-90, 2^90].
*
* Relative error < 0.0013%.
*
@ -274,32 +273,32 @@ static inline float bw_sin2pif(float x);
/*! <<<```
* Returns an approximation of the sine of 2 * pi * `x`, where `x` is given
* in radians.
*
* Absolute error < 0.011 or relative error < 1.7%, whatever is worse.
*
* `x` must be finite.
*
* Absolute error < 0.011 or relative error < 1.7%, whatever is worse.
*
* #### bw_sinf()
* ```>>> */
static inline float bw_sinf(float x);
/*! <<<```
* Returns an approximation of the sine of `x`, where `x` is given in
* radians.
*
* Absolute error < 0.011 or relative error < 1.7%, whatever is worse.
*
* `x` must be finite.
*
* Absolute error < 0.011 or relative error < 1.7%, whatever is worse.
*
* #### bw_cos2pif()
* ```>>> */
static inline float bw_cos2pif(float x);
/*! <<<```
* Returns an approximation of the cosine of 2 * pi * `x`, where `x` is given
* in radians.
*
* Absolute error < 0.011 or relative error < 1.7%, whatever is worse.
*
* `x` must be finite.
*
* Absolute error < 0.011 or relative error < 1.7%, whatever is worse.
*
* #### bw_cosf()
* ```>>> */
@ -307,11 +306,11 @@ static inline float bw_cosf(float x);
/*! <<<```
* Returns an approximation of the cosine of `x`, where `x` is given in
* radians.
*
* Absolute error < 0.011 or relative error < 1.7%, whatever is worse.
*
* `x` must be finite.
*
* Absolute error < 0.011 or relative error < 1.7%, whatever is worse.
*
* #### bw_tan2pif()
* ```>>> */
static inline float bw_tan2pif(float x);
@ -319,36 +318,32 @@ static inline float bw_tan2pif(float x);
* Returns an approximation of the tangent of 2 * pi * `x`, where `x` is
* given in radians.
*
* Not guaranteed to work for `x` too close to singularities. Safe
* range: `x` in [-1/4 + 5e-4f / pi, 1/4 - 5e-4f / pi] + k / 2, where k is
* any integer number.
*
* `x` must be finite and in [-1/4 + 5e-4f / pi, 1/4 - 5e-4f / pi] + k / 2,
* where k is any integer number.
*
* Absolute error < 0.06 or relative error < 0.8%, whatever is worse.
*
* `x` must be finite.
*
* #### bw_tanf()
* ```>>> */
static inline float bw_tanf(float x);
/*! <<<```
* Returns an approximation of the tangent of `x`, where `x` is given in
* radians.
*
* Not guaranteed to work for `x` too close to singularities. Safe
* range: `x` in [-pi/2 + 1e-3f, pi/2 - 1e-3f] + k * pi, where k is any
* integer number.
*
* `x` must be finite and in [-pi/2 + 1e-3f, pi/2 - 1e-3f] + k * pi, where k
* is any integer number.
*
* Absolute error < 0.06 or relative error < 0.8%, whatever is worse.
*
* `x` must be finite.
*
* #### bw_log2f()
* ```>>> */
static inline float bw_log2f(float x);
/*! <<<```
* Returns an approximation of the base-2 logarithm of `x`.
*
* `x` must be finite and greater than or equal to `1.175494350822287e-38f`.
*
* Absolute error < 0.0055, relative error < 1.5%.
* Absolute error < 0.0055 or relative error < 1.2%, whatever is worse.
*
* #### bw_logf()
* ```>>> */
@ -356,15 +351,19 @@ static inline float bw_logf(float x);
/*! <<<```
* Returns an approximation of the natural logarithm of `x`.
*
* Absolute error < 0.0039, relative error < 1.5%.
* `x` must be finite and greater than or equal to `1.175494350822287e-38f`.
*
* Absolute error < 0.0038 or relative error < 1.2%, whatever is worse.
*
* #### bw_log10f()
* ```>>> */
static inline float bw_log10f(float x);
/*! <<<```
* Returns an approximation of the base-10 logarithm of `x`.
*
* Absolute error < 0.0017, relative error < 1.5%.
*
* `x` must be finite and greater than or equal to `1.175494350822287e-38f`.
*
* Absolute error < 0.0017 or relative error < 1.2%, whatever is worse.
*
* #### bw_pow2f()
* ```>>> */
@ -406,7 +405,7 @@ static inline float bw_lin2dBf(float x);
* Returns an approximation of 20 times the base-10 logarithm of `x` (linear
* ratio to dB conversion).
*
* Absolute error < 0.032, relative error < 1.5%.
* Absolute error < 0.032, relative error < 1.2%.
*
* #### bw_sqrtf()
* ```>>> */

View File

@ -58,8 +58,8 @@ int n_ko = 0;
v_expr.f = expr; \
v_expected.f = expected; \
float err_abs = fabsf(v_expr.f - v_expected.f); \
float err_rel = fabsf(v_expected.f) < tol_abs ? 0.f : fabsf((v_expr.f - v_expected.f) / v_expected.f); \
if (err_abs <= tol_abs && err_rel <= tol_rel) { \
float err_rel = fabsf((v_expr.f - v_expected.f) / v_expected.f); \
if (err_abs <= tol_abs || err_rel <= tol_rel) { \
printf("✔ %s = %g (expected %g, err %g|%g%%, tol %g|%g%%)\n", #expr, v_expr.f, v_expected.f, err_abs, err_rel * 100.f, tol_abs, tol_rel * 100.f); \
n_ok++; \
} else { \
@ -837,6 +837,78 @@ int main() {
TEST_ABS_REL(bw_tanf(-56.78f), tanf(-56.78f), 0.06f, 0.008);
TEST_ABS_REL(bw_tanf(-567.8f), tanf(-567.8f), 0.06f, 0.008);
TEST_ABS_REL(bw_tanf(-5678.f), tanf(-5678.f), 0.06f, 0.008);
TEST_ABS_REL(bw_log2f(1.175494350822287e-38f), -126.f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(1.e-30f), -9.965784284662087e+01f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(1.438449888287666e-27f), -8.916754359960814e+01f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(2.069138081114798e-24f), -7.867724435259542e+01f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(2.976351441631313e-21f), -6.818694510558271e+01f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(4.281332398719396e-18f), -5.769664585856998e+01f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(6.158482110660280e-15f), -4.720634661155725e+01f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(8.858667904100795e-12f), -3.671604736454454e+01f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(1.274274985703132e-08f), -2.622574811753181e+01f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(1.832980710832437e-05f), -1.573544887051908e+01f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(2.636650898730366e-02f), -5.245149623506357e+00f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(1.f), 0.f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(1.3f), 0.378511623253730f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(3.792690190732238e+01f), 5.245149623506357e+00f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(5.455594781168515e+04f), 1.573544887051908e+01f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(7.847599703514622e+07f), 2.622574811753181e+01f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(1.128837891684693e+11f), 3.671604736454454e+01f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(1.623776739188718e+14f), 4.720634661155725e+01f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(2.335721469090121e+17f), 5.769664585856998e+01f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(3.359818286283788e+20f), 6.818694510558271e+01f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(4.832930238571732e+23f), 7.867724435259542e+01f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(6.951927961775592e+26f), 8.916754359960814e+01f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_log2f(1e+30f), 9.965784284662087e+01f, 0.0055f, 0.012f);
TEST_ABS_REL(bw_logf(1.175494350822287e-38f), -87.33654475055312f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(1.e-30f), -6.907755278982137e+01f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(1.438449888287666e-27f), -6.180623144352438e+01f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(2.069138081114798e-24f), -5.453491009722740e+01f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(2.976351441631313e-21f), -4.726358875093041e+01f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(4.281332398719396e-18f), -3.999226740463342e+01f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(6.158482110660280e-15f), -3.272094605833644e+01f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(8.858667904100795e-12f), -2.544962471203945e+01f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(1.274274985703132e-08f), -1.817830336574247e+01f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(1.832980710832437e-05f), -1.090698201944548e+01f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(2.636650898730366e-02f), -3.635660673148490e+00f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(1.f), 0.f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(1.3f), 0.262364264467491f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(3.792690190732238e+01f), 3.635660673148490e+00f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(5.455594781168515e+04f), 1.090698201944548e+01f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(7.847599703514622e+07f), 1.817830336574247e+01f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(1.128837891684693e+11f), 2.544962471203945e+01f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(1.623776739188718e+14f), 3.272094605833644e+01f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(2.335721469090121e+17f), 3.999226740463342e+01f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(3.359818286283788e+20f), 4.726358875093041e+01f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(4.832930238571732e+23f), 5.453491009722740e+01f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(6.951927961775592e+26f), 6.180623144352438e+01f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_logf(1e+30f), 6.907755278982137e+01f, 0.0038f, 0.012f);
TEST_ABS_REL(bw_log10f(1.175494350822287e-38f), -37.92977945366163f, 0.0017f, 0.012f);
TEST_ABS_REL(bw_log10f(1.e-30f), -3.000000000000000e+01f, 0.0017f, 0.012f);
TEST_ABS_REL(bw_log10f(1.438449888287666e-27f), -2.684210526315789e+01f, 0.0017f, 0.012f);
TEST_ABS_REL(bw_log10f(2.069138081114798e-24f), -2.368421052631579e+01f, 0.0017f, 0.012f);
TEST_ABS_REL(bw_log10f(2.976351441631313e-21f), -2.052631578947368e+01f, 0.0017f, 0.012f);
TEST_ABS_REL(bw_log10f(4.281332398719396e-18f), -1.736842105263158e+01f, 0.0017f, 0.012f);
TEST_ABS_REL(bw_log10f(6.158482110660280e-15f), -1.421052631578947e+01f, 0.0017f, 0.012f);
TEST_ABS_REL(bw_log10f(8.858667904100795e-12f), -1.105263157894737e+01f, 0.0017f, 0.012f);
TEST_ABS_REL(bw_log10f(1.274274985703132e-08f), -7.894736842105264e+00f, 0.0017f, 0.012f);
TEST_ABS_REL(bw_log10f(1.832980710832437e-05f), -4.736842105263158e+00f, 0.0017f, 0.012f);
TEST_ABS_REL(bw_log10f(2.636650898730366e-02f), -1.578947368421051e+00f, 0.0017f, 0.012f);
TEST_ABS_REL(bw_log10f(1.f), 0.f, 0.0017f, 0.012f);
TEST_ABS_REL(bw_log10f(1.3f), 0.113943352306837f, 0.0017f, 0.012f);
TEST_ABS_REL(bw_log10f(3.792690190732238e+01f), 1.578947368421051e+00f, 0.0017f, 0.012f);
TEST_ABS_REL(bw_log10f(5.455594781168515e+04f), 4.736842105263158e+00f, 0.0017f, 0.012f);
TEST_ABS_REL(bw_log10f(7.847599703514622e+07f), 7.894736842105264e+00f, 0.0017f, 0.012f);
TEST_ABS_REL(bw_log10f(1.128837891684693e+11f), 1.105263157894737e+01f, 0.0017f, 0.012f);
TEST_ABS_REL(bw_log10f(1.623776739188718e+14f), 1.421052631578947e+01f, 0.0017f, 0.012f);
TEST_ABS_REL(bw_log10f(2.335721469090121e+17f), 1.736842105263158e+01f, 0.0017f, 0.012f);
TEST_ABS_REL(bw_log10f(3.359818286283788e+20f), 2.052631578947368e+01f, 0.0017f, 0.012f);
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);
printf("\nsuceeded: %d, failed: %d\n\n", n_ok, n_ko);