Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // FILE: __functions.h
- //
- // fast and approximate transcendental functions
- //
- // copyright (c) 2004 Robert Bristow-Johnson
- //
- //
- #ifndef __FUNCTIONS_H
- #define __FUNCTIONS_H
- #define TINY 1.0e-8
- #define HUGE 1.0e8
- #define PI (3.1415926535897932384626433832795028841972) /* pi */
- #define ONE_OVER_PI (0.3183098861837906661338147750939)
- #define TWOPI (6.2831853071795864769252867665590057683943) /* 2*pi */
- #define ONE_OVER_TWOPI (0.15915494309189535682609381638)
- #define PI_2 (1.5707963267948966192313216916397514420986) /* pi/2 */
- #define TWO_OVER_PI (0.636619772367581332267629550188)
- #define LN2 (0.6931471805599453094172321214581765680755) /* ln(2) */
- #define ONE_OVER_LN2 (1.44269504088896333066907387547)
- #define LN10 (2.3025850929940456840179914546843642076011) /* ln(10) */
- #define ONE_OVER_LN10 (0.43429448190325177635683940025)
- #define ROOT2 (1.4142135623730950488016887242096980785697) /* sqrt(2) */
- #define ONE_OVER_ROOT2 (0.707106781186547438494264988549)
- #define DB_LOG2_ENERGY (3.01029995663981154631945610163) /* dB = DB_LOG2_ENERGY*__log2(energy) */
- #define DB_LOG2_AMPL (6.02059991327962309263891220326) /* dB = DB_LOG2_AMPL*__log2(amplitude) */
- #define ONE_OVER_DB_LOG2_AMPL (0.16609640474436811218256075335) /* amplitude = __exp2(ONE_OVER_DB_LOG2_AMPL*dB) */
- #define LONG_OFFSET 4096L
- #define FLOAT_OFFSET 4096.0
- float __sqrt(float x);
- float __log2(float x);
- float __exp2(float x);
- float __log(float x);
- float __exp(float x);
- float __pow(float x, float y);
- float __sin_pi(float x);
- float __cos_pi(float x);
- float __sin(float x);
- float __cos(float x);
- float __tan(float x);
- float __atan(float x);
- float __asin(float x);
- float __acos(float x);
- float __arg(float Imag, float Real);
- float __poly(float *a, int order, float x);
- float __map(float *f, float scaler, float x);
- float __discreteMap(float *f, float scaler, float x);
- unsigned long __random();
- #endif
- //
- // FILE: __functions.c
- //
- // fast and approximate transcendental functions
- //
- // copyright (c) 2004 Robert Bristow-Johnson
- //
- //
- #define STD_MATH_LIB 0
- #include "__functions.h"
- #if STD_MATH_LIB
- #include "math.h" // angle brackets don't work with SE markup
- #endif
- float __sqrt(register float x)
- {
- #if STD_MATH_LIB
- return (float)sqrt((double)x);
- #else
- if (x > 5.877471754e-39)
- {
- register float accumulator, xPower;
- register long intPart;
- register union { float f; long i; } xBits;
- xBits.f = x;
- intPart = ((xBits.i) >> 23); /* get biased exponent */
- intPart -= 127; /* unbias it */
- x = (float)(xBits.i & 0x007FFFFF); /* mask off exponent leaving 0x800000*(mantissa - 1) */
- x *= 1.192092895507812e-07; /* divide by 0x800000 */
- accumulator = 1.0 + 0.49959804148061*x;
- xPower = x * x;
- accumulator += -0.12047308243453*xPower;
- xPower *= x;
- accumulator += 0.04585425015501*xPower;
- xPower *= x;
- accumulator += -0.01076564682800*xPower;
- if (intPart & 0x00000001)
- {
- accumulator *= ROOT2; /* an odd input exponent means an extra sqrt(2) in the output */
- }
- xBits.i = intPart >> 1; /* divide exponent by 2, lose LSB */
- xBits.i += 127; /* rebias exponent */
- xBits.i <<= 23; /* move biased exponent into exponent bits */
- return accumulator * xBits.f;
- }
- else
- {
- return 0.0;
- }
- #endif
- }
- float __log2(register float x)
- {
- #if STD_MATH_LIB
- return (float)(ONE_OVER_LN2*log((double)x));
- #else
- if (x > 5.877471754e-39)
- {
- register float accumulator, xPower;
- register long intPart;
- register union { float f; long i; } xBits;
- xBits.f = x;
- intPart = ((xBits.i) >> 23); /* get biased exponent */
- intPart -= 127; /* unbias it */
- x = (float)(xBits.i & 0x007FFFFF); /* mask off exponent leaving 0x800000*(mantissa - 1) */
- x *= 1.192092895507812e-07; /* divide by 0x800000 */
- accumulator = 1.44254494359510*x;
- xPower = x * x;
- accumulator += -0.71814525675041*xPower;
- xPower *= x;
- accumulator += 0.45754919692582*xPower;
- xPower *= x;
- accumulator += -0.27790534462866*xPower;
- xPower *= x;
- accumulator += 0.12179791068782*xPower;
- xPower *= x;
- accumulator += -0.02584144982967*xPower;
- return accumulator + (float)intPart;
- }
- else
- {
- return -HUGE;
- }
- #endif
- }
- float __exp2(register float x)
- {
- #if STD_MATH_LIB
- return (float)exp(LN2*(double)x);
- #else
- if (x >= -127.0)
- {
- register float accumulator, xPower;
- register union { float f; long i; } xBits;
- xBits.i = (long)(x + FLOAT_OFFSET) - LONG_OFFSET; /* integer part */
- x -= (float)(xBits.i); /* fractional part */
- accumulator = 1.0 + 0.69303212081966*x;
- xPower = x * x;
- accumulator += 0.24137976293709*xPower;
- xPower *= x;
- accumulator += 0.05203236900844*xPower;
- xPower *= x;
- accumulator += 0.01355574723481*xPower;
- xBits.i += 127; /* bias integer part */
- xBits.i <<= 23; /* move biased int part into exponent bits */
- return accumulator * xBits.f;
- }
- else
- {
- return 0.0;
- }
- #endif
- }
- float __log(register float x)
- {
- #if STD_MATH_LIB
- return (float)log((double)x);
- #else
- return LN2 * __log2(x);
- #endif
- }
- float __exp(register float x)
- {
- #if STD_MATH_LIB
- return (float)exp((double)x);
- #else
- return __exp2(ONE_OVER_LN2*x);
- #endif
- }
- float __pow(float x, float y)
- {
- #if STD_MATH_LIB
- return (float)pow((double)x, (double)y);
- #else
- return __exp2(y*__log2(x));
- #endif
- }
- float __sin_pi(register float x)
- {
- #if STD_MATH_LIB
- return (float)sin(PI*(double)x);
- #else
- register float accumulator, xPower, xSquared;
- register long evenIntPart = ((long)(0.5*x + 1024.5) - 1024) << 1;
- x -= (float)evenIntPart;
- xSquared = x * x;
- accumulator = 3.14159265358979*x;
- xPower = xSquared * x;
- accumulator += -5.16731953364340*xPower;
- xPower *= xSquared;
- accumulator += 2.54620566822659*xPower;
- xPower *= xSquared;
- accumulator += -0.586027023087261*xPower;
- xPower *= xSquared;
- accumulator += 0.06554823491427*xPower;
- return accumulator;
- #endif
- }
- float __cos_pi(register float x)
- {
- #if STD_MATH_LIB
- return (float)cos(PI*(double)x);
- #else
- register float accumulator, xPower, xSquared;
- register long evenIntPart = ((long)(0.5*x + 1024.5) - 1024) << 1;
- x -= (float)evenIntPart;
- xSquared = x * x;
- accumulator = 1.57079632679490*x; /* series for sin(PI/2*x) */
- xPower = xSquared * x;
- accumulator += -0.64596406188166*xPower;
- xPower *= xSquared;
- accumulator += 0.07969158490912*xPower;
- xPower *= xSquared;
- accumulator += -0.00467687997706*xPower;
- xPower *= xSquared;
- accumulator += 0.00015303015470*xPower;
- return 1.0 - 2.0*accumulator*accumulator; /* cos(w) = 1 - 2*(sin(w/2))^2 */
- #endif
- }
- float __sin(register float x)
- {
- #if STD_MATH_LIB
- return (float)sin((double)x);
- #else
- x *= ONE_OVER_PI;
- return __sin_pi(x);
- #endif
- }
- float __cos(register float x)
- {
- #if STD_MATH_LIB
- return (float)cos((double)x);
- #else
- x *= ONE_OVER_PI;
- return __cos_pi(x);
- #endif
- }
- float __tan(register float x)
- {
- #if STD_MATH_LIB
- return (float)tan((double)x);
- #else
- x *= ONE_OVER_PI;
- return __sin_pi(x) / __cos_pi(x);
- #endif
- }
- float __atan(register float x)
- {
- #if STD_MATH_LIB
- return (float)atan((double)x);
- #else
- register float accumulator, xPower, xSquared, offset;
- offset = 0.0;
- if (x < -1.0)
- {
- offset = -PI_2;
- x = -1.0 / x;
- }
- else if (x > 1.0)
- {
- offset = PI_2;
- x = -1.0 / x;
- }
- xSquared = x * x;
- accumulator = 1.0;
- xPower = xSquared;
- accumulator += 0.33288950512027*xPower;
- xPower *= xSquared;
- accumulator += -0.08467922817644*xPower;
- xPower *= xSquared;
- accumulator += 0.03252232640125*xPower;
- xPower *= xSquared;
- accumulator += -0.00749305860992*xPower;
- return offset + x / accumulator;
- #endif
- }
- float __asin(register float x)
- {
- #if STD_MATH_LIB
- return (float)asin((double)x);
- #else
- return __atan(x / __sqrt(1.0 - x * x));
- #endif
- }
- float __acos(register float x)
- {
- #if STD_MATH_LIB
- return (float)acos((double)x);
- #else
- return __atan(__sqrt(1.0 - x * x) / x);
- #endif
- }
- float __arg(float Imag, float Real)
- {
- #if STD_MATH_LIB
- return (float)atan2((double)Imag, (double)Real);
- #else
- register float accumulator, xPower, xSquared, offset, x;
- if (Imag > 0.0)
- {
- if (Imag <= -Real)
- {
- offset = PI;
- x = Imag / Real;
- }
- else if (Imag > Real)
- {
- offset = PI_2;
- x = -Real / Imag;
- }
- else
- {
- offset = 0.0;
- x = Imag / Real;
- }
- }
- else
- {
- if (Imag >= Real)
- {
- offset = -PI;
- x = Imag / Real;
- }
- else if (Imag < -Real)
- {
- offset = -PI_2;
- x = -Real / Imag;
- }
- else
- {
- offset = 0.0;
- x = Imag / Real;
- }
- }
- xSquared = x * x;
- accumulator = 1.0;
- xPower = xSquared;
- accumulator += 0.33288950512027*xPower;
- xPower *= xSquared;
- accumulator += -0.08467922817644*xPower;
- xPower *= xSquared;
- accumulator += 0.03252232640125*xPower;
- xPower *= xSquared;
- accumulator += -0.00749305860992*xPower;
- return offset + x / accumulator;
- #endif
- }
- float __poly(float *a, int order, float x)
- {
- register float accumulator = 0.0, xPower;
- register int n;
- accumulator = a[0];
- xPower = x;
- for (n = 1; n <= order; n++)
- {
- accumulator += a[n] * xPower;
- xPower *= x;
- }
- return accumulator;
- }
- float __map(float *f, float scaler, float x)
- {
- register long i;
- x *= scaler;
- i = (long)(x + FLOAT_OFFSET) - LONG_OFFSET; /* round down without floor() */
- return f[i] + (f[i + 1] - f[i])*(x - (float)i); /* linear interpolate between points */
- }
- float __discreteMap(float *f, float scaler, float x)
- {
- register long i;
- x *= scaler;
- i = (long)(x + (FLOAT_OFFSET + 0.5)) - LONG_OFFSET; /* round to nearest */
- return f[i];
- }
- unsigned long __random()
- {
- static unsigned long seed0 = 0x5B7A2775, seed1 = 0x80C7169F;
- seed0 += seed1;
- seed1 += seed0;
- return seed1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement