e_expf.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       e_expf.c (2864B)
       ---
            1 /* e_expf.c -- float version of e_exp.c.
            2  * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
            3  */
            4 
            5 /*
            6  * ====================================================
            7  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
            8  *
            9  * Developed at SunPro, a Sun Microsystems, Inc. business.
           10  * Permission to use, copy, modify, and distribute this
           11  * software is freely granted, provided that this notice
           12  * is preserved.
           13  * ====================================================
           14  */
           15 
           16 #ifndef lint
           17 static char rcsid[] = "$FreeBSD: src/lib/msun/src/e_expf.c,v 1.7 2002/05/28 17:03:12 alfred Exp $";
           18 #endif
           19 
           20 #include "math.h"
           21 #include "math_private.h"
           22 
           23 static const float
           24 one        = 1.0,
           25 halF[2]        = {0.5,-0.5,},
           26 huge        = 1.0e+30,
           27 twom100 = 7.8886090522e-31,      /* 2**-100=0x0d800000 */
           28 o_threshold=  8.8721679688e+01,  /* 0x42b17180 */
           29 u_threshold= -1.0397208405e+02,  /* 0xc2cff1b5 */
           30 ln2HI[2]   ={ 6.9313812256e-01,                /* 0x3f317180 */
           31              -6.9313812256e-01,},        /* 0xbf317180 */
           32 ln2LO[2]   ={ 9.0580006145e-06,          /* 0x3717f7d1 */
           33              -9.0580006145e-06,},        /* 0xb717f7d1 */
           34 invln2 =  1.4426950216e+00,                 /* 0x3fb8aa3b */
           35 P1   =  1.6666667163e-01, /* 0x3e2aaaab */
           36 P2   = -2.7777778450e-03, /* 0xbb360b61 */
           37 P3   =  6.6137559770e-05, /* 0x388ab355 */
           38 P4   = -1.6533901999e-06, /* 0xb5ddea0e */
           39 P5   =  4.1381369442e-08; /* 0x3331bb4c */
           40 
           41 float
           42 __ieee754_expf(float x)        /* default IEEE double exp */
           43 {
           44         float y,hi=0.0,lo=0.0,c,t;
           45         int32_t k=0,xsb;
           46         u_int32_t hx;
           47 
           48         GET_FLOAT_WORD(hx,x);
           49         xsb = (hx>>31)&1;                /* sign bit of x */
           50         hx &= 0x7fffffff;                /* high word of |x| */
           51 
           52     /* filter out non-finite argument */
           53         if(hx >= 0x42b17218) {                        /* if |x|>=88.721... */
           54             if(hx>0x7f800000)
           55                  return x+x;                         /* NaN */
           56             if(hx==0x7f800000)
           57                 return (xsb==0)? x:0.0;                /* exp(+-inf)={inf,0} */
           58             if(x > o_threshold) return huge*huge; /* overflow */
           59             if(x < u_threshold) return twom100*twom100; /* underflow */
           60         }
           61 
           62     /* argument reduction */
           63         if(hx > 0x3eb17218) {                /* if  |x| > 0.5 ln2 */
           64             if(hx < 0x3F851592) {        /* and |x| < 1.5 ln2 */
           65                 hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb;
           66             } else {
           67                 k  = invln2*x+halF[xsb];
           68                 t  = k;
           69                 hi = x - t*ln2HI[0];        /* t*ln2HI is exact here */
           70                 lo = t*ln2LO[0];
           71             }
           72             x  = hi - lo;
           73         }
           74         else if(hx < 0x31800000)  {        /* when |x|<2**-28 */
           75             if(huge+x>one) return one+x;/* trigger inexact */
           76         }
           77         else k = 0;
           78 
           79     /* x is now in primary range */
           80         t  = x*x;
           81         c  = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
           82         if(k==0)         return one-((x*c)/(c-(float)2.0)-x);
           83         else                 y = one-((lo-(x*c)/((float)2.0-c))-hi);
           84         if(k >= -125) {
           85             u_int32_t hy;
           86             GET_FLOAT_WORD(hy,y);
           87             SET_FLOAT_WORD(y,hy+(k<<23));        /* add k to y's exponent */
           88             return y;
           89         } else {
           90             u_int32_t hy;
           91             GET_FLOAT_WORD(hy,y);
           92             SET_FLOAT_WORD(y,hy+((k+100)<<23));        /* add k to y's exponent */
           93             return y*twom100;
           94         }
           95 }