bw_math

A collection of mathematical routines that strive to be better suited to DSP than, e.g., those supplied by your C standard library.

Such a goal is hopefully accomplished by:

  • being as branchless as reasonable/convenient;
  • not handling uninteresting corner cases, such as out-of-range, NaN, and sometimes infinity input values (out-of-range and NaN inputs are always considered invalid and lead to undefined behavior);
  • returning approximated results (indicated in this documentation);
  • making no distinction between 0.f and -0.f.

In practice they should guarantee fast and consistent performance, but always do your own benchmarking.

All functions in this module are reentrant, RT-safe, thread-safe, and have no side effects.

API

Module type: Utility

bw_signfilli32()

static inline int32_t bw_signfilli32(
	int32_t x);

Returns ~0 if x is negative, 0 otherwise.

bw_mini32()

static inline int32_t bw_mini32(
	int32_t a,
	int32_t b);

Returns the minimum of a and b.

bw_maxi32()

static inline int32_t bw_maxi32(
	int32_t a,
	int32_t b);

Returns the maximum of a and b.

bw_clipi32()

static inline int32_t bw_clipi32(
	int32_t x,
	int32_t m,
	int32_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_minu32()

static inline uint32_t bw_minu32(
	uint32_t a,
	uint32_t b);

Returns the minimum of a and b.

bw_maxu32()

static inline uint32_t bw_maxu32(
	uint32_t a,
	uint32_t b);

Returns the maximum of a and b.

bw_clipu32()

static inline uint32_t bw_clipu32(
	uint32_t x,
	uint32_t m,
	uint32_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_signfilli64()

static inline int64_t bw_signfilli64(
	int64_t x);

Returns ~0 if x is negative, 0 otherwise.

bw_mini64()

static inline int64_t bw_mini64(
	int64_t a,
	int64_t b);

Returns the minimum of a and b.

bw_maxi64()

static inline int64_t bw_maxi64(
	int64_t a,
	int64_t b);

Returns the maximum of a and b.

bw_clipi64()

static inline int64_t bw_clipi64(
	int64_t x,
	int64_t m,
	int64_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_minu32()

static inline uint64_t bw_minu64(
	uint64_t a,
	uint64_t b);

Returns the minimum of a and b.

bw_maxu64()

static inline uint64_t bw_maxu64(
	uint64_t a,
	uint64_t b);

Returns the maximum of a and b.

bw_clipu64()

static inline uint64_t bw_clipu64(
	uint64_t x,
	uint64_t m,
	uint64_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_copysignf()

static inline float bw_copysignf(
	float x,
	float y);

Returns a value that has the absolute value of x and the sign of y.

bw_signf()

static inline float bw_signf(
	float x);

Returns 1.f if x > 0.f, -1.f if x < 0.f and 0.f if x == 0.f.

bw_absf()

static inline float bw_absf(
	float x);

Returns the absolute value of x.

bw_min0f()

static inline float bw_min0f(
	float x);

Returns the minimum of 0.f and x.

bw_max0f()

static inline float bw_max0f(
	float x);

Returns the maximum of 0.f and x.

bw_minf()

static inline float bw_minf(
	float a,
	float b);

Returns the minimum of a and b.

bw_maxf()

static inline float bw_maxf(
	float a,
	float b);

Returns the maximum of a and b.

bw_clipf()

static inline float bw_clipf(
	float x,
	float m,
	float 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.

M must be greater than or equal to m.

bw_truncf()

static inline float bw_truncf(
	float x);

Returns x with its fractional part set to zero (i.e., rounded towards zero).

x must be finite.

bw_roundf()

static inline float bw_roundf(
	float x);

Returns x rounded to the nearest integer.

Halfway cases are rounded away from zero. E.g., bw_roundf(0.5f) gives 1.f and bw_roundf(-0.5f) gives -1.f.

x must be finite.

bw_floorf()

static inline float bw_floorf(
	float x);

Returns the biggest integer less or equal than x (i.e., x is rounded down).

x must be finite.

bw_ceilf()

static inline float bw_ceilf(
	float x);

Returns the smallest integer greater or equal than x (i.e., x is rounded up).

x must be finite.

bw_intfracf()

static inline void bw_intfracf(
	float               x,
	float * BW_RESTRICT i,
	float * BW_RESTRICT f);

Puts the integer part (floor) of x in i and the fractional part in f.

x must be finite.

bw_rcpf()

static inline float bw_rcpf(
	float x);

Returns the reciprocal of x (i.e., 1.f / x).

|x| must be in [8.077935669463161e-28f, 1.237940039285380e+27].

Relative error < 0.0013%.

bw_sin2pif()

static inline float bw_sin2pif(
	float x);

Returns an approximation of the sine of 2 * pi * x, where x is given in radians.

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.

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.

x must be finite.

Absolute error < 0.011 or relative error < 1.7%, whatever is worse.

bw_cosf()

static inline float bw_cosf(
	float x);

Returns an approximation of the cosine of x, where x is given in radians.

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);

Returns an approximation of the tangent of 2 * pi * x, where x is given in radians.

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.

bw_tanf()

static inline float bw_tanf(
	float x);

Returns an approximation of the tangent of x, where x is given in radians.

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.

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 or relative error < 1.2%, whatever is worse.

bw_logf()

static inline float bw_logf(
	float x);

Returns an approximation of the natural logarithm of x.

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.

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()

static inline float bw_pow2f(
	float 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()

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. For x < -37.92977945366162f it just returns 0.

x must be less than or equal to 38.531f.

Relative error < 0.062%.

bw_log2_1p2xf()

static inline float bw_log2_1p2xf(
	float x);

Returns an approximation of log2(1+2^x).

Absolute error < 0.006.

bw_log_1pexpxf()

static inline float bw_log_1pexpxf(
	float x);

Returns an approximation of log(1+exp(x)).

Absolute error < 0.004.

bw_log10_1p10xf()

static inline float bw_log10_1p10xf(
	float x);

Returns an approximation of log10(1+10^x).

Absolute error < 0.002.

bw_dB2linf()

static inline float bw_dB2linf(
	float x);

Returns an approximation of 10 raised to the power of x / 20 (dB to linear ratio conversion). For x < -758.5955890732315f it just returns 0.f.

x must be less than or equal to 770.630f.

Relative error < 0.062%.

bw_lin2dBf()

static inline float bw_lin2dBf(
	float x);

Returns an approximation of 20 times the base-10 logarithm of x (linear ratio to dB conversion).

x must be finite and greater than or equal to 1.175494350822287e-38f.

Absolute error < 0.032 or relative error < 1.2%, whatever is worse.

bw_sqrtf()

static inline float bw_sqrtf(
	float x);

Returns an approximation of the square root of x.

x must be finite and non-negative.

Absolute error < 1.09e-19 or relative error < 0.0007%, whatever is worse.

bw_tanhf()

static inline float bw_tanhf(
	float x);

Returns an approximation of the hyperbolic tangent of x.

Absolute error < 0.035 or relative error < 6.5%, whatever is worse.

bw_sinhf()

static inline float bw_sinhf(
	float x);

Returns an approximation of the hyperbolic sine of x.

|x| must less than or equal to 88.722f.

Absolute error < 1e-7 or relative error < 0.07%, whatever is worse.

bw_coshf()

static inline float bw_coshf(
	float x);

Returns an approximation of the hyperbolic cosine of x.

|x| must less than or equal to 88.722f.

Relative error < 0.07%.

bw_asinhf()

static inline float bw_asinhf(
	float x);

Returns an approximation of the hyperbolic arcsine of x.

|x| must less than or equal to 8.507059173023462e+37f.

Absolute error < 0.004 or relative error < 1.2%, whatever is worse.

bw_acoshf()

static inline float bw_acoshf(
	float x);

Returns an approximation of the hyperbolic arccosine of x.

x must be in [1.f, 8.507059173023462e+37f].

Absolute error < 0.004 or relative error < 0.8%, whatever is worse.

Changelog

  • Version 1.1.0:
    • Added bw_signfilli64(), bw_mini64(), bw_maxi64(), bw_clipi64(), bw_minu64(), bw_maxu64(), bw_clipu64(), bw_log2_1p2xf(), bw_log_1pexpxf(), and bw_log10_1p10xf().
    • Added support for BW_INCLUDE_WITH_QUOTES and BW_CXX_NO_EXTERN_C.
  • Version 1.0.1:
    • Now using BW_NULL.
    • Fixed sign-related warnings in bw_truncf(), bw_roundf(), and bw_sqrtf().
  • Version 1.0.0:
    • Renamed bw_min0xf() as bw_min0f() and bw_max0xf() as bw_max0f().
    • Removed precision suffixes from function names.
    • New implementations for bw_min0f(), bw_max0f(), bw_minf(), bw_maxf(), and bw_clipf().
    • Fixed rounding bug in bw_roundf() when absolute value of input was in [0.5f, 1.f].
    • Fixed bw_ceilf() for negative input values.
    • Fixed bw_sqrtf() for very large input values and improved implementation.
    • Fixed input validity ranges in bw_asinhf() and bw_acoshf().
    • Added BW_RESTRICT specifiers to input arguments of bw_intfracf().
    • Removed usage of reserved identifiers and designated initializers.
    • Added extern "C" to functions.
    • Added more debugging checks in bw_intfracf().
    • Improved documentation w.r.t. validity of input values and approximation errors.
  • Version 0.6.0:
    • Added debugging code.
    • Removed dependency on bw_config.
    • Removed bw_omega_3log() and bw_omega_3lognr().
    • Fixed bw_pow10f_3() and bw_acoshf_3().
  • Version 0.4.0:
    • Added bw_ceilf(), bw_intfracf(), bw_sinhf_3(), bw_coshf_3(), bw_asinhf_3(), and bw_acoshf_3().
  • Version 0.3.0:
    • Added bw_log10f_3(), bw_pow10f_3(), bw_dB2linf_3(), and bw_lin2dBf_3().
    • Fixed computation bug in bw_sqrtf_2().
  • Version 0.2.0:
    • Added bw_sin2pif_3(), bw_cos2pif_3(), bw_tan2pif_3(), bw_omega_3lognr(), and bw_tanhf_3().
  • Version 0.1.0:
    • First release.