diff options
Diffstat (limited to 'libm/float/exp10f.c')
| -rw-r--r-- | libm/float/exp10f.c | 115 | 
1 files changed, 115 insertions, 0 deletions
| diff --git a/libm/float/exp10f.c b/libm/float/exp10f.c new file mode 100644 index 000000000..c7c62c567 --- /dev/null +++ b/libm/float/exp10f.c @@ -0,0 +1,115 @@ +/*							exp10f.c + * + *	Base 10 exponential function + *      (Common antilogarithm) + * + * + * + * SYNOPSIS: + * + * float x, y, exp10f(); + * + * y = exp10f( x ); + * + * + * + * DESCRIPTION: + * + * Returns 10 raised to the x power. + * + * Range reduction is accomplished by expressing the argument + * as 10**x = 2**n 10**f, with |f| < 0.5 log10(2). + * A polynomial approximates 10**f. + * + * + * + * ACCURACY: + * + *                      Relative error: + * arithmetic   domain     # trials      peak         rms + *    IEEE      -38,+38     100000      9.8e-8      2.8e-8 + * + * ERROR MESSAGES: + * + *   message         condition      value returned + * exp10 underflow    x < -MAXL10        0.0 + * exp10 overflow     x > MAXL10       MAXNUM + * + * IEEE single arithmetic: MAXL10 = 38.230809449325611792. + * + */ + +/* +Cephes Math Library Release 2.2:  June, 1992 +Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier +Direct inquiries to 30 Frost Street, Cambridge, MA 02140 +*/ + + +#include <math.h> + +static float P[] = { + 2.063216740311022E-001, + 5.420251702225484E-001, + 1.171292686296281E+000, + 2.034649854009453E+000, + 2.650948748208892E+000, + 2.302585167056758E+000 +}; + +/*static float LOG102 = 3.01029995663981195214e-1;*/ +static float LOG210 = 3.32192809488736234787e0; +static float LG102A = 3.00781250000000000000E-1; +static float LG102B = 2.48745663981195213739E-4; +static float MAXL10 = 38.230809449325611792; + + + + +extern float MAXNUMF; + +float floorf(float), ldexpf(float, int), polevlf(float, float *, int); + +float exp10f(float xx) +{ +float x, px, qx; +short n; + +x = xx; +if( x > MAXL10 ) +	{ +	mtherr( "exp10f", OVERFLOW ); +	return( MAXNUMF ); +	} + +if( x < -MAXL10 )	/* Would like to use MINLOG but can't */ +	{ +	mtherr( "exp10f", UNDERFLOW ); +	return(0.0); +	} + +/* The following is necessary because range reduction blows up: */ +if( x == 0 ) +	return(1.0); + +/* Express 10**x = 10**g 2**n + *   = 10**g 10**( n log10(2) ) + *   = 10**( g + n log10(2) ) + */ +px = x * LOG210; +qx = floorf( px + 0.5 ); +n = qx; +x -= qx * LG102A; +x -= qx * LG102B; + +/* rational approximation for exponential + * of the fractional part: + * 10**x - 1  =  2x P(x**2)/( Q(x**2) - P(x**2) ) + */ +px = 1.0 + x * polevlf( x, P, 5 ); + +/* multiply by power of 2 */ +x = ldexpf( px, n ); + +return(x); +} | 
