add missing int math and tests, improve log_1px

This commit is contained in:
Stefano D'Angelo 2025-06-07 09:21:05 +02:00
parent 18c7d41d87
commit 523d4477aa
3 changed files with 516 additions and 3 deletions

View File

@ -47,6 +47,10 @@
* <li>Version <strong>1.2.0</strong>: * <li>Version <strong>1.2.0</strong>:
* <ul> * <ul>
* <li>Added <code>bw_sechf()</code>.</li> * <li>Added <code>bw_sechf()</code>.</li>
* <li>Added <code>bw_{signfill,min,max,clip}{i,u}{8,16}()</code>.</li>
* <li>Improved precision and performance of
* <code>bw_log_1pexpxf()</code>, and
* <code>bw_log10_1p10xf()</code>.</li>
* </ul> * </ul>
* </li> * </li>
* <li>Version <strong>1.1.0</strong>: * <li>Version <strong>1.1.0</strong>:
@ -151,6 +155,124 @@ extern "C" {
/*** Public API ***/ /*** Public API ***/
/*! api {{{ /*! api {{{
* #### bw_signfilli8()
* ```>>> */
static inline int8_t bw_signfilli8(
int8_t x);
/*! <<<```
* Returns `~0` if `x` is negative, `0` otherwise.
*
* #### bw_mini8()
* ```>>> */
static inline int8_t bw_mini8(
int8_t a,
int8_t b);
/*! <<<```
* Returns the minimum of `a` and `b`.
*
* #### bw_maxi8()
* ```>>> */
static inline int8_t bw_maxi8(
int8_t a,
int8_t b);
/*! <<<```
* Returns the maximum of `a` and `b`.
*
* #### bw_clipi8()
* ```>>> */
static inline int8_t bw_clipi8(
int8_t x,
int8_t m,
int8_t M);
/*! <<<```
* Returns `x` unless it is smaller than `m`, in which case it returns `m`,
* or bigger than `M`, in which case it returns `M`.
*
* #### bw_minu8()
* ```>>> */
static inline uint8_t bw_minu8(
uint8_t a,
uint8_t b);
/*! <<<```
* Returns the minimum of `a` and `b`.
*
* #### bw_maxu8()
* ```>>> */
static inline uint8_t bw_maxu8(
uint8_t a,
uint8_t b);
/*! <<<```
* Returns the maximum of `a` and `b`.
*
* #### bw_clipu8()
* ```>>> */
static inline uint8_t bw_clipu8(
uint8_t x,
uint8_t m,
uint8_t M);
/*! <<<```
* Returns `x` unless it is smaller than `m`, in which case it returns `m`,
* or bigger than `M`, in which case it returns `M`.
*
* #### bw_signfilli16()
* ```>>> */
static inline int16_t bw_signfilli16(
int16_t x);
/*! <<<```
* Returns `~0` if `x` is negative, `0` otherwise.
*
* #### bw_mini16()
* ```>>> */
static inline int16_t bw_mini16(
int16_t a,
int16_t b);
/*! <<<```
* Returns the minimum of `a` and `b`.
*
* #### bw_maxi16()
* ```>>> */
static inline int16_t bw_maxi16(
int16_t a,
int16_t b);
/*! <<<```
* Returns the maximum of `a` and `b`.
*
* #### bw_clipi16()
* ```>>> */
static inline int16_t bw_clipi16(
int16_t x,
int16_t m,
int16_t M);
/*! <<<```
* Returns `x` unless it is smaller than `m`, in which case it returns `m`,
* or bigger than `M`, in which case it returns `M`.
*
* #### bw_minu16()
* ```>>> */
static inline uint16_t bw_minu16(
uint16_t a,
uint16_t b);
/*! <<<```
* Returns the minimum of `a` and `b`.
*
* #### bw_maxu16()
* ```>>> */
static inline uint16_t bw_maxu16(
uint16_t a,
uint16_t b);
/*! <<<```
* Returns the maximum of `a` and `b`.
*
* #### bw_clipu16()
* ```>>> */
static inline uint16_t bw_clipu16(
uint16_t x,
uint16_t m,
uint16_t M);
/*! <<<```
* Returns `x` unless it is smaller than `m`, in which case it returns `m`,
* or bigger than `M`, in which case it returns `M`.
*
* #### bw_signfilli32() * #### bw_signfilli32()
* ```>>> */ * ```>>> */
static inline int32_t bw_signfilli32( static inline int32_t bw_signfilli32(
@ -682,6 +804,92 @@ extern "C" {
// I hope the target architecture and compiler will use conditional ops here // I hope the target architecture and compiler will use conditional ops here
static inline int8_t bw_signfilli8(
int8_t x) {
return x < 0 ? ~0 : 0;
}
static inline int8_t bw_mini8(
int8_t a,
int8_t b) {
return a < b ? a : b;
}
static inline int8_t bw_maxi8(
int8_t a,
int8_t b) {
return a > b ? a : b;
}
static inline int8_t bw_clipi8(
int8_t x,
int8_t m,
int8_t M) {
return x < m ? m : (x > M ? M : x);
}
static inline uint8_t bw_minu8(
uint8_t a,
uint8_t b) {
return a < b ? a : b;
}
static inline uint8_t bw_maxu8(
uint8_t a,
uint8_t b) {
return a > b ? a : b;
}
static inline uint8_t bw_clipu8(
uint8_t x,
uint8_t m,
uint8_t M) {
return x < m ? m : (x > M ? M : x);
}
static inline int16_t bw_signfilli16(
int16_t x) {
return x < 0 ? ~0 : 0;
}
static inline int16_t bw_mini16(
int16_t a,
int16_t b) {
return a < b ? a : b;
}
static inline int16_t bw_maxi16(
int16_t a,
int16_t b) {
return a > b ? a : b;
}
static inline int16_t bw_clipi16(
int16_t x,
int16_t m,
int16_t M) {
return x < m ? m : (x > M ? M : x);
}
static inline uint16_t bw_minu16(
uint16_t a,
uint16_t b) {
return a < b ? a : b;
}
static inline uint16_t bw_maxu16(
uint16_t a,
uint16_t b) {
return a > b ? a : b;
}
static inline uint16_t bw_clipu16(
uint16_t x,
uint16_t m,
uint16_t M) {
return x < m ? m : (x > M ? M : x);
}
static inline int32_t bw_signfilli32( static inline int32_t bw_signfilli32(
int32_t x) { int32_t x) {
return x < 0 ? ~0 : 0; return x < 0 ? ~0 : 0;
@ -1078,7 +1286,7 @@ static inline float bw_log2_1p2xf(
static inline float bw_log_1pexpxf( static inline float bw_log_1pexpxf(
float x) { float x) {
BW_ASSERT(!bw_is_nan(x)); BW_ASSERT(!bw_is_nan(x));
const float y = 0.693147180559945f * bw_log2_1p2xf(1.442695040888963f * x); const float y = x >= 22.18070977791827f ? x : 0.693147180559945f * bw_log2f(1.f + bw_pow2f(1.442695040888963f * x));
BW_ASSERT(bw_is_finite(y)); BW_ASSERT(bw_is_finite(y));
return y; return y;
} }
@ -1086,7 +1294,7 @@ static inline float bw_log_1pexpxf(
static inline float bw_log10_1p10xf( static inline float bw_log10_1p10xf(
float x) { float x) {
BW_ASSERT(!bw_is_nan(x)); BW_ASSERT(!bw_is_nan(x));
const float y = 0.3010299956639811f * bw_log2_1p2xf(3.321928094887363f * x); const float y = x >= 9.632959861247409f ? x : 0.3010299956639811f * bw_log2f(1.f + bw_pow2f(3.321928094887363f * x));
BW_ASSERT(bw_is_finite(y)); BW_ASSERT(bw_is_finite(y));
return y; return y;
} }

View File

@ -5,7 +5,7 @@ all: build/bw_math
./build/bw_math ./build/bw_math
build/bw_math: bw_math.c ../include/bw_math.h | build build/bw_math: bw_math.c ../include/bw_math.h | build
${CC} ${CFLAGS} bw_math.c -o $@ ${CC} ${CFLAGS} bw_math.c -o $@ -lm
build: build:
mkdir -p $@ mkdir -p $@

View File

@ -68,6 +68,43 @@ int n_ko = 0;
} \ } \
} }
#define TEST_ABS(expr, expected, tol_abs) \
{ \
union { float f; uint32_t u; } v_expr, v_expected; \
v_expr.f = expr; \
v_expected.f = expected; \
float err_abs = fabsf(v_expr.f - v_expected.f); \
if (err_abs <= tol_abs) { \
printf("✔ %s = %g (expected %g, err %g, tol %g)\n", #expr, v_expr.f, v_expected.f, err_abs, tol_abs); \
n_ok++; \
} else { \
printf("✘ %s = %g [0x%x] (expected %g [0x%x], err %g, tol %g) - line %d\n", #expr, v_expr.f, v_expr.u, v_expected.f, v_expected.u, err_abs, tol_abs, __LINE__); \
n_ko++; \
} \
}
static float log2_1p2xf(float x) {
if (x > 30.f)
return x;
return log2f(1.f + powf(2.f, x));
}
static float log_1pexpxf(float x) {
if (x > 25.f)
return x;
return logf(1.f + expf(x));
}
static float log10_1p10xf(float x) {
if (x > 10.f)
return x;
return log10f(1.f + powf(10.f, x));
}
static float xsechf(float x) {
return 1.f / coshf(x);
}
int main() { int main() {
printf("\nbw_math unit tests\n"); printf("\nbw_math unit tests\n");
printf("------------------\n\n"); printf("------------------\n\n");
@ -1179,6 +1216,73 @@ int main() {
TEST_REL(bw_coshf(70.f), coshf(70.f), 0.0007f); TEST_REL(bw_coshf(70.f), coshf(70.f), 0.0007f);
TEST_REL(bw_coshf(80.f), coshf(80.f), 0.0007f); TEST_REL(bw_coshf(80.f), coshf(80.f), 0.0007f);
TEST_ABS_REL(bw_sechf(-1e37f), xsechf(-1e37f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-1e30f), xsechf(-1e30f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-1e20f), xsechf(-1e20f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-1e10f), xsechf(-1e10f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-1e5f), xsechf(-1e5f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-100.f), xsechf(-100.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-80.f), xsechf(-80.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-70.f), xsechf(-70.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-60.f), xsechf(-60.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-50.f), xsechf(-50.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-40.f), xsechf(-40.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-30.f), xsechf(-30.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-20.f), xsechf(-20.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-10.f), xsechf(-10.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-9.f), xsechf(-9.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-8.f), xsechf(-8.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-7.f), xsechf(-7.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-6.f), xsechf(-6.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-5.f), xsechf(-5.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-4.f), xsechf(-4.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-3.f), xsechf(-3.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-2.f), xsechf(-2.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-1.f), xsechf(-1.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-1e-1f), xsechf(-1e-1f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-1e-2f), xsechf(-1e-2f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-1e-3f), xsechf(-1e-3f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-1e-4f), xsechf(-1e-4f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-1e-5f), xsechf(-1e-5f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-1e-6f), xsechf(-1e-6f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-1e-7f), xsechf(-1e-7f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-1e-8f), xsechf(-1e-8f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-1e-9f), xsechf(-1e-9f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(-0.f), xsechf(0.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(0.f), xsechf(0.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(1e-9f), xsechf(1e-9f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(1e-8f), xsechf(1e-8f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(1e-7f), xsechf(1e-7f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(1e-6f), xsechf(1e-6f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(1e-5f), xsechf(1e-5f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(1e-4f), xsechf(1e-4f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(1e-3f), xsechf(1e-3f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(1e-2f), xsechf(1e-2f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(1e-1f), xsechf(1e-1f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(1.f), xsechf(1.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(2.f), xsechf(2.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(3.f), xsechf(3.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(4.f), xsechf(4.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(5.f), xsechf(5.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(6.f), xsechf(6.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(7.f), xsechf(7.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(8.f), xsechf(8.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(9.f), xsechf(9.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(10.f), xsechf(10.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(20.f), xsechf(20.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(30.f), xsechf(30.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(40.f), xsechf(40.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(50.f), xsechf(50.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(60.f), xsechf(60.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(70.f), xsechf(70.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(80.f), xsechf(80.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(100.f), xsechf(100.f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(1e5f), xsechf(1e5f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(1e10f), xsechf(1e10f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(1e20f), xsechf(1e20f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(1e30f), xsechf(1e30f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_sechf(1e37f), xsechf(1e37f), 1e-9f, 0.0007f);
TEST_ABS_REL(bw_asinhf(-1e37f), asinhf(-1e37f), 0.004f, 0.012f); TEST_ABS_REL(bw_asinhf(-1e37f), asinhf(-1e37f), 0.004f, 0.012f);
TEST_ABS_REL(bw_asinhf(-1e30f), asinhf(-1e30f), 0.004f, 0.012f); TEST_ABS_REL(bw_asinhf(-1e30f), asinhf(-1e30f), 0.004f, 0.012f);
TEST_ABS_REL(bw_asinhf(-1e20f), asinhf(-1e20f), 0.004f, 0.012f); TEST_ABS_REL(bw_asinhf(-1e20f), asinhf(-1e20f), 0.004f, 0.012f);
@ -1270,6 +1374,207 @@ int main() {
TEST_ABS_REL(bw_acoshf(1e30f), acoshf(1e30f), 0.004f, 0.008f); TEST_ABS_REL(bw_acoshf(1e30f), acoshf(1e30f), 0.004f, 0.008f);
TEST_ABS_REL(bw_acoshf(1e37f), acoshf(1e37f), 0.004f, 0.008f); TEST_ABS_REL(bw_acoshf(1e37f), acoshf(1e37f), 0.004f, 0.008f);
TEST_ABS(bw_log2_1p2xf(-1e37f), log2_1p2xf(-1e37f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-1e30f), log2_1p2xf(-1e30f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-1e20f), log2_1p2xf(-1e20f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-1e10f), log2_1p2xf(-1e10f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-1e5f), log2_1p2xf(-1e5f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-100.f), log2_1p2xf(-100.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-80.f), log2_1p2xf(-80.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-70.f), log2_1p2xf(-70.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-60.f), log2_1p2xf(-60.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-50.f), log2_1p2xf(-50.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-40.f), log2_1p2xf(-40.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-30.f), log2_1p2xf(-30.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-20.f), log2_1p2xf(-20.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-10.f), log2_1p2xf(-10.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-9.f), log2_1p2xf(-9.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-8.f), log2_1p2xf(-8.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-7.f), log2_1p2xf(-7.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-6.f), log2_1p2xf(-6.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-5.f), log2_1p2xf(-5.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-4.f), log2_1p2xf(-4.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-3.f), log2_1p2xf(-3.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-2.f), log2_1p2xf(-2.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-1.f), log2_1p2xf(-1.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-1e-1f), log2_1p2xf(-1e-1f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-1e-2f), log2_1p2xf(-1e-2f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-1e-3f), log2_1p2xf(-1e-3f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-1e-4f), log2_1p2xf(-1e-4f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-1e-5f), log2_1p2xf(-1e-5f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-1e-6f), log2_1p2xf(-1e-6f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-1e-7f), log2_1p2xf(-1e-7f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-1e-8f), log2_1p2xf(-1e-8f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-1e-9f), log2_1p2xf(-1e-9f), 0.006f);
TEST_ABS(bw_log2_1p2xf(-0.f), log2_1p2xf(-0.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(0.f), log2_1p2xf(0.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(1e-9f), log2_1p2xf(1e-9f), 0.006f);
TEST_ABS(bw_log2_1p2xf(1e-8f), log2_1p2xf(1e-8f), 0.006f);
TEST_ABS(bw_log2_1p2xf(1e-7f), log2_1p2xf(1e-7f), 0.006f);
TEST_ABS(bw_log2_1p2xf(1e-6f), log2_1p2xf(1e-6f), 0.006f);
TEST_ABS(bw_log2_1p2xf(1e-5f), log2_1p2xf(1e-5f), 0.006f);
TEST_ABS(bw_log2_1p2xf(1e-4f), log2_1p2xf(1e-4f), 0.006f);
TEST_ABS(bw_log2_1p2xf(1e-3f), log2_1p2xf(1e-3f), 0.006f);
TEST_ABS(bw_log2_1p2xf(1e-2f), log2_1p2xf(1e-2f), 0.006f);
TEST_ABS(bw_log2_1p2xf(1e-1f), log2_1p2xf(1e-1f), 0.006f);
TEST_ABS(bw_log2_1p2xf(1.f), log2_1p2xf(1.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(2.f), log2_1p2xf(2.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(3.f), log2_1p2xf(3.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(4.f), log2_1p2xf(4.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(5.f), log2_1p2xf(5.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(6.f), log2_1p2xf(6.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(7.f), log2_1p2xf(7.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(8.f), log2_1p2xf(8.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(9.f), log2_1p2xf(9.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(10.f), log2_1p2xf(10.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(20.f), log2_1p2xf(20.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(30.f), log2_1p2xf(30.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(40.f), log2_1p2xf(40.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(50.f), log2_1p2xf(50.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(60.f), log2_1p2xf(60.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(70.f), log2_1p2xf(70.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(80.f), log2_1p2xf(80.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(100.f), log2_1p2xf(100.f), 0.006f);
TEST_ABS(bw_log2_1p2xf(1e5f), log2_1p2xf(1e5f), 0.006f);
TEST_ABS(bw_log2_1p2xf(1e10f), log2_1p2xf(1e10f), 0.006f);
TEST_ABS(bw_log2_1p2xf(1e20f), log2_1p2xf(1e20f), 0.006f);
TEST_ABS(bw_log2_1p2xf(1e30f), log2_1p2xf(1e30f), 0.006f);
TEST_ABS(bw_log2_1p2xf(1e37f), log2_1p2xf(1e37f), 0.006f);
TEST_ABS(bw_log_1pexpxf(-1e37f), log_1pexpxf(-1e37f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-1e30f), log_1pexpxf(-1e30f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-1e20f), log_1pexpxf(-1e20f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-1e10f), log_1pexpxf(-1e10f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-1e5f), log_1pexpxf(-1e5f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-100.f), log_1pexpxf(-100.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-80.f), log_1pexpxf(-80.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-70.f), log_1pexpxf(-70.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-60.f), log_1pexpxf(-60.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-50.f), log_1pexpxf(-50.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-40.f), log_1pexpxf(-40.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-30.f), log_1pexpxf(-30.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-20.f), log_1pexpxf(-20.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-10.f), log_1pexpxf(-10.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-9.f), log_1pexpxf(-9.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-8.f), log_1pexpxf(-8.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-7.f), log_1pexpxf(-7.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-6.f), log_1pexpxf(-6.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-5.f), log_1pexpxf(-5.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-4.f), log_1pexpxf(-4.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-3.f), log_1pexpxf(-3.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-2.f), log_1pexpxf(-2.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-1.f), log_1pexpxf(-1.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-1e-1f), log_1pexpxf(-1e-1f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-1e-2f), log_1pexpxf(-1e-2f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-1e-3f), log_1pexpxf(-1e-3f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-1e-4f), log_1pexpxf(-1e-4f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-1e-5f), log_1pexpxf(-1e-5f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-1e-6f), log_1pexpxf(-1e-6f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-1e-7f), log_1pexpxf(-1e-7f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-1e-8f), log_1pexpxf(-1e-8f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-1e-9f), log_1pexpxf(-1e-9f), 0.004f);
TEST_ABS(bw_log_1pexpxf(-0.f), log_1pexpxf(-0.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(0.f), log_1pexpxf(0.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(1e-9f), log_1pexpxf(1e-9f), 0.004f);
TEST_ABS(bw_log_1pexpxf(1e-8f), log_1pexpxf(1e-8f), 0.004f);
TEST_ABS(bw_log_1pexpxf(1e-7f), log_1pexpxf(1e-7f), 0.004f);
TEST_ABS(bw_log_1pexpxf(1e-6f), log_1pexpxf(1e-6f), 0.004f);
TEST_ABS(bw_log_1pexpxf(1e-5f), log_1pexpxf(1e-5f), 0.004f);
TEST_ABS(bw_log_1pexpxf(1e-4f), log_1pexpxf(1e-4f), 0.004f);
TEST_ABS(bw_log_1pexpxf(1e-3f), log_1pexpxf(1e-3f), 0.004f);
TEST_ABS(bw_log_1pexpxf(1e-2f), log_1pexpxf(1e-2f), 0.004f);
TEST_ABS(bw_log_1pexpxf(1e-1f), log_1pexpxf(1e-1f), 0.004f);
TEST_ABS(bw_log_1pexpxf(1.f), log_1pexpxf(1.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(2.f), log_1pexpxf(2.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(3.f), log_1pexpxf(3.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(4.f), log_1pexpxf(4.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(5.f), log_1pexpxf(5.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(6.f), log_1pexpxf(6.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(7.f), log_1pexpxf(7.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(8.f), log_1pexpxf(8.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(9.f), log_1pexpxf(9.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(10.f), log_1pexpxf(10.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(20.f), log_1pexpxf(20.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(30.f), log_1pexpxf(30.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(40.f), log_1pexpxf(40.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(50.f), log_1pexpxf(50.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(60.f), log_1pexpxf(60.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(70.f), log_1pexpxf(70.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(80.f), log_1pexpxf(80.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(100.f), log_1pexpxf(100.f), 0.004f);
TEST_ABS(bw_log_1pexpxf(1e5f), log_1pexpxf(1e5f), 0.004f);
TEST_ABS(bw_log_1pexpxf(1e10f), log_1pexpxf(1e10f), 0.004f);
TEST_ABS(bw_log_1pexpxf(1e20f), log_1pexpxf(1e20f), 0.004f);
TEST_ABS(bw_log_1pexpxf(1e30f), log_1pexpxf(1e30f), 0.004f);
TEST_ABS(bw_log_1pexpxf(1e37f), log_1pexpxf(1e37f), 0.004f);
TEST_ABS(bw_log10_1p10xf(-1e37f), log10_1p10xf(-1e37f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-1e30f), log10_1p10xf(-1e30f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-1e20f), log10_1p10xf(-1e20f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-1e10f), log10_1p10xf(-1e10f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-1e5f), log10_1p10xf(-1e5f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-100.f), log10_1p10xf(-100.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-80.f), log10_1p10xf(-80.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-70.f), log10_1p10xf(-70.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-60.f), log10_1p10xf(-60.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-50.f), log10_1p10xf(-50.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-40.f), log10_1p10xf(-40.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-30.f), log10_1p10xf(-30.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-20.f), log10_1p10xf(-20.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-10.f), log10_1p10xf(-10.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-9.f), log10_1p10xf(-9.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-8.f), log10_1p10xf(-8.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-7.f), log10_1p10xf(-7.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-6.f), log10_1p10xf(-6.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-5.f), log10_1p10xf(-5.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-4.f), log10_1p10xf(-4.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-3.f), log10_1p10xf(-3.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-2.f), log10_1p10xf(-2.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-1.f), log10_1p10xf(-1.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-1e-1f), log10_1p10xf(-1e-1f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-1e-2f), log10_1p10xf(-1e-2f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-1e-3f), log10_1p10xf(-1e-3f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-1e-4f), log10_1p10xf(-1e-4f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-1e-5f), log10_1p10xf(-1e-5f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-1e-6f), log10_1p10xf(-1e-6f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-1e-7f), log10_1p10xf(-1e-7f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-1e-8f), log10_1p10xf(-1e-8f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-1e-9f), log10_1p10xf(-1e-9f), 0.002f);
TEST_ABS(bw_log10_1p10xf(-0.f), log10_1p10xf(-0.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(0.f), log10_1p10xf(0.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(1e-9f), log10_1p10xf(1e-9f), 0.002f);
TEST_ABS(bw_log10_1p10xf(1e-8f), log10_1p10xf(1e-8f), 0.002f);
TEST_ABS(bw_log10_1p10xf(1e-7f), log10_1p10xf(1e-7f), 0.002f);
TEST_ABS(bw_log10_1p10xf(1e-6f), log10_1p10xf(1e-6f), 0.002f);
TEST_ABS(bw_log10_1p10xf(1e-5f), log10_1p10xf(1e-5f), 0.002f);
TEST_ABS(bw_log10_1p10xf(1e-4f), log10_1p10xf(1e-4f), 0.002f);
TEST_ABS(bw_log10_1p10xf(1e-3f), log10_1p10xf(1e-3f), 0.002f);
TEST_ABS(bw_log10_1p10xf(1e-2f), log10_1p10xf(1e-2f), 0.002f);
TEST_ABS(bw_log10_1p10xf(1e-1f), log10_1p10xf(1e-1f), 0.002f);
TEST_ABS(bw_log10_1p10xf(1.f), log10_1p10xf(1.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(2.f), log10_1p10xf(2.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(3.f), log10_1p10xf(3.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(4.f), log10_1p10xf(4.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(5.f), log10_1p10xf(5.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(6.f), log10_1p10xf(6.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(7.f), log10_1p10xf(7.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(8.f), log10_1p10xf(8.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(9.f), log10_1p10xf(9.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(10.f), log10_1p10xf(10.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(20.f), log10_1p10xf(20.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(30.f), log10_1p10xf(30.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(40.f), log10_1p10xf(40.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(50.f), log10_1p10xf(50.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(60.f), log10_1p10xf(60.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(70.f), log10_1p10xf(70.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(80.f), log10_1p10xf(80.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(100.f), log10_1p10xf(100.f), 0.002f);
TEST_ABS(bw_log10_1p10xf(1e5f), log10_1p10xf(1e5f), 0.002f);
TEST_ABS(bw_log10_1p10xf(1e10f), log10_1p10xf(1e10f), 0.002f);
TEST_ABS(bw_log10_1p10xf(1e20f), log10_1p10xf(1e20f), 0.002f);
TEST_ABS(bw_log10_1p10xf(1e30f), log10_1p10xf(1e30f), 0.002f);
TEST_ABS(bw_log10_1p10xf(1e37f), log10_1p10xf(1e37f), 0.002f);
printf("\nsuceeded: %d, failed: %d\n\n", n_ok, n_ko); printf("\nsuceeded: %d, failed: %d\n\n", n_ok, n_ko);
return n_ko ? EXIT_FAILURE : EXIT_SUCCESS; return n_ko ? EXIT_FAILURE : EXIT_SUCCESS;