home *** CD-ROM | disk | FTP | other *** search
- /* exp10.c
- *
- * Base 10 exponential function
- * (Common antilogarithm)
- *
- *
- *
- * SYNOPSIS:
- *
- * double x, y, exp10();
- *
- * y = exp10( 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).
- * The Pade' form
- *
- * 2x P(x**2)/( Q(x**2) - P(x**2) )
- *
- * is used to approximate 10**f - 1.
- *
- *
- *
- * ACCURACY:
- *
- * Relative error:
- * arithmetic domain # trials peak rms
- * DEC -38,+38 47000 2.7e-17 6.2e-18
- * IEEE -308,+308 30000 4.4e-16 6.2e-17
- *
- * ERROR MESSAGES:
- *
- * message condition value returned
- * exp10 underflow x < -MAXL10 0.0
- * exp10 overflow x > MAXL10 MAXNUM
- *
- * DEC arithmetic: MAXL10 = 38.230809449325611792.
- * IEEE arithmetic: MAXL10 = 308.2547155599167.
- *
- */
-
- /*
- Cephes Math Library Release 2.1: December, 1988
- Copyright 1984, 1987, 1988 by Stephen L. Moshier
- Direct inquiries to 30 Frost Street, Cambridge, MA 02140
- */
-
-
- #include "mconf.h"
-
- #ifdef UNK
- static double P[] = {
- 7.67176747836011812180E-2,
- 6.08131766159694132207E0,
- 4.12967835799494649943E1
- };
- static double Q[] = {
- /* 1.00000000000000000000E0,*/
- 2.11303917828964245249E1,
- 3.58699304582497404950E1
- };
- static double LOG102 = 3.01029995663981195214e-1;
- static double LOG210 = 3.32192809488736234787e0;
- static double L102A = 3.00781250000000000000E-1;
- static double L102B = 2.48745663981195213739E-4
- static double MAXL10 = 38.230809449325611792;
- #endif
-
- #ifdef DEC
- static short P[] = {
- 0037235,0017050,0000704,0007227,
- 0040702,0115047,0077444,0126202,
- 0041445,0027750,0004347,0076663
- };
- static short Q[] = {
- /*0040200,0000000,0000000,0000000,*/
- 0041251,0005412,0154331,0124200,
- 0041417,0075317,0006317,0164140
- };
- static short L102[] = {
- 0037632,0020232,0102373,0147770
- };
- #define LOG102 *(double *)L102
- static short L210[] = {
- 0040524,0115170,0045715,0015613
- };
- #define LOG210 *(double *)L210
- static short L102A[] = {
- 0037632,0000000,0000000,0000000
- };
- #define LG102A *(double *)L102A
- static short L102B[] = {
- 0035202,0065023,0167477,0157142
- };
- #define LG102B *(double *)L102B
- static short MXL[] = {
- 0041430,0166131,0047761,0154130,
- };
- #define MAXL10 ( *(double *)MXL )
- #endif
-
- #ifdef IBMPC
- static short P[] = {
- 0x81d3,0x0038,0xa3c5,0x3fb3,
- 0x9590,0xefe4,0x5344,0x4018,
- 0xefb6,0x011c,0xa5fd,0x4044
- };
- static short Q[] = {
- /*0x0000,0x0000,0x0000,0x3ff0,*/
- 0x3510,0x5b1b,0x2161,0x4035,
- 0xfd0c,0xe199,0xef59,0x4041
- };
- static short L102[] = {
- 0x79ff,0x509f,0x4413,0x3fd3
- };
- #define LOG102 *(double *)L102
- static short L210[] = {
- 0xa371,0x0979,0x934f,0x400a
- };
- #define LOG210 *(double *)L210
- static short L102A[] = {
- 0x0000,0x0000,0x4000,0x3fd3
- };
- #define LG102A *(double *)L102A
- static short L102B[] = {
- 0xfbcc,0x7de7,0x4d42,0x3f30
- };
- #define LG102B *(double *)L102B
- static double MAXL10 = 308.2547155599167;
- #endif
-
- #ifdef MIEEE
- static short P[] = {
- 0x3fb3,0xa3c5,0x0038,0x81d3,
- 0x4018,0x5344,0xefe4,0x9590,
- 0x4044,0xa5fd,0x011c,0xefb6
- };
- static short Q[] = {
- 0x4035,0x2161,0x5b1b,0x3510,
- 0x4041,0xef59,0xe199,0xfd0c
- };
- static short L102[] = {
- 0x3fd3,0x4413,0x509f,0x79ff
- };
- #define LOG102 *(double *)L102
- static short L210[] = {
- 0x400a,0x934f,0x0979,0xa371
- };
- #define LOG210 *(double *)L210
- static short L102A[] = {
- 0x3fd3,0x4000,0x0000,0x0000
- };
- #define LG102A *(double *)L102A
- static short L102B[] = {
- 0x3f30,0x4d42,0x7de7,0xfbcc
- };
- #define LG102B *(double *)L102B
- static double MAXL10 = 308.2547155599167;
- #endif
-
-
-
- extern double MAXNUM;
-
- double exp10(x)
- double x;
- {
- double px, qx, xx;
- short n;
- double floor(), ldexp(), polevl(), p1evl();
-
- if( x > MAXL10 )
- {
- mtherr( "exp10", OVERFLOW );
- return( MAXNUM );
- }
-
- if( x < -MAXL10 ) /* Would like to use MINLOG but can't */
- {
- mtherr( "exp10", 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 = floor( 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) )
- */
- xx = x * x;
- px = x * polevl( xx, P, 2 );
- x = px/( p1evl( xx, Q, 2 ) - px );
- x = ldexp( x, 1 );
- x = x + 1.0;
-
- /* multiply by power of 2 */
- x = ldexp( x, n );
-
- return(x);
- }
-