Path: blob/master/src/java.base/share/native/libfdlibm/e_exp.c
41149 views
/*1* Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/* __ieee754_exp(x)26* Returns the exponential of x.27*28* Method29* 1. Argument reduction:30* Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658.31* Given x, find r and integer k such that32*33* x = k*ln2 + r, |r| <= 0.5*ln2.34*35* Here r will be represented as r = hi-lo for better36* accuracy.37*38* 2. Approximation of exp(r) by a special rational function on39* the interval [0,0.34658]:40* Write41* R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ...42* We use a special Reme algorithm on [0,0.34658] to generate43* a polynomial of degree 5 to approximate R. The maximum error44* of this polynomial approximation is bounded by 2**-59. In45* other words,46* R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**547* (where z=r*r, and the values of P1 to P5 are listed below)48* and49* | 5 | -5950* | 2.0+P1*z+...+P5*z - R(z) | <= 251* | |52* The computation of exp(r) thus becomes53* 2*r54* exp(r) = 1 + -------55* R - r56* r*R1(r)57* = 1 + r + ----------- (for better accuracy)58* 2 - R1(r)59* where60* 2 4 1061* R1(r) = r - (P1*r + P2*r + ... + P5*r ).62*63* 3. Scale back to obtain exp(x):64* From step 1, we have65* exp(x) = 2^k * exp(r)66*67* Special cases:68* exp(INF) is INF, exp(NaN) is NaN;69* exp(-INF) is 0, and70* for finite argument, only exp(0)=1 is exact.71*72* Accuracy:73* according to an error analysis, the error is always less than74* 1 ulp (unit in the last place).75*76* Misc. info.77* For IEEE double78* if x > 7.09782712893383973096e+02 then exp(x) overflow79* if x < -7.45133219101941108420e+02 then exp(x) underflow80*81* Constants:82* The hexadecimal values are the intended ones for the following83* constants. The decimal values may be used, provided that the84* compiler will convert from decimal to binary accurately enough85* to produce the hexadecimal values shown.86*/8788#include "fdlibm.h"8990#ifdef __STDC__91static const double92#else93static double94#endif95one = 1.0,96halF[2] = {0.5,-0.5,},97huge = 1.0e+300,98twom1000= 9.33263618503218878990e-302, /* 2**-1000=0x01700000,0*/99o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */100u_threshold= -7.45133219101941108420e+02, /* 0xc0874910, 0xD52D3051 */101ln2HI[2] ={ 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */102-6.93147180369123816490e-01,},/* 0xbfe62e42, 0xfee00000 */103ln2LO[2] ={ 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */104-1.90821492927058770002e-10,},/* 0xbdea39ef, 0x35793c76 */105invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */106P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */107P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */108P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */109P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */110P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */111112113#ifdef __STDC__114double __ieee754_exp(double x) /* default IEEE double exp */115#else116double __ieee754_exp(x) /* default IEEE double exp */117double x;118#endif119{120double y,hi=0,lo=0,c,t;121int k=0,xsb;122unsigned hx;123124hx = __HI(x); /* high word of x */125xsb = (hx>>31)&1; /* sign bit of x */126hx &= 0x7fffffff; /* high word of |x| */127128/* filter out non-finite argument */129if(hx >= 0x40862E42) { /* if |x|>=709.78... */130if(hx>=0x7ff00000) {131if(((hx&0xfffff)|__LO(x))!=0)132return x+x; /* NaN */133else return (xsb==0)? x:0.0; /* exp(+-inf)={inf,0} */134}135if(x > o_threshold) return huge*huge; /* overflow */136if(x < u_threshold) return twom1000*twom1000; /* underflow */137}138139/* argument reduction */140if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */141if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */142hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb;143} else {144k = invln2*x+halF[xsb];145t = k;146hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */147lo = t*ln2LO[0];148}149x = hi - lo;150}151else if(hx < 0x3e300000) { /* when |x|<2**-28 */152if(huge+x>one) return one+x;/* trigger inexact */153}154else k = 0;155156/* x is now in primary range */157t = x*x;158c = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));159if(k==0) return one-((x*c)/(c-2.0)-x);160else y = one-((lo-(x*c)/(2.0-c))-hi);161if(k >= -1021) {162__HI(y) += (k<<20); /* add k to y's exponent */163return y;164} else {165__HI(y) += ((k+1000)<<20);/* add k to y's exponent */166return y*twom1000;167}168}169170171