1 |
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
2 |
* |
3 |
* ***** BEGIN LICENSE BLOCK ***** |
4 |
* Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
5 |
* |
6 |
* The contents of this file are subject to the Mozilla Public License Version |
7 |
* 1.1 (the "License"); you may not use this file except in compliance with |
8 |
* the License. You may obtain a copy of the License at |
9 |
* http://www.mozilla.org/MPL/ |
10 |
* |
11 |
* Software distributed under the License is distributed on an "AS IS" basis, |
12 |
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
13 |
* for the specific language governing rights and limitations under the |
14 |
* License. |
15 |
* |
16 |
* The Original Code is Mozilla Communicator client code, released |
17 |
* March 31, 1998. |
18 |
* |
19 |
* The Initial Developer of the Original Code is |
20 |
* Sun Microsystems, Inc. |
21 |
* Portions created by the Initial Developer are Copyright (C) 1998 |
22 |
* the Initial Developer. All Rights Reserved. |
23 |
* |
24 |
* Contributor(s): |
25 |
* |
26 |
* Alternatively, the contents of this file may be used under the terms of |
27 |
* either of the GNU General Public License Version 2 or later (the "GPL"), |
28 |
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
29 |
* in which case the provisions of the GPL or the LGPL are applicable instead |
30 |
* of those above. If you wish to allow use of your version of this file only |
31 |
* under the terms of either the GPL or the LGPL, and not to allow others to |
32 |
* use your version of this file under the terms of the MPL, indicate your |
33 |
* decision by deleting the provisions above and replace them with the notice |
34 |
* and other provisions required by the GPL or the LGPL. If you do not delete |
35 |
* the provisions above, a recipient may use your version of this file under |
36 |
* the terms of any one of the MPL, the GPL or the LGPL. |
37 |
* |
38 |
* ***** END LICENSE BLOCK ***** */ |
39 |
|
40 |
/* @(#)e_exp.c 1.3 95/01/18 */ |
41 |
/* |
42 |
* ==================================================== |
43 |
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
44 |
* |
45 |
* Developed at SunSoft, a Sun Microsystems, Inc. business. |
46 |
* Permission to use, copy, modify, and distribute this |
47 |
* software is freely granted, provided that this notice |
48 |
* is preserved. |
49 |
* ==================================================== |
50 |
*/ |
51 |
|
52 |
/* __ieee754_exp(x) |
53 |
* Returns the exponential of x. |
54 |
* |
55 |
* Method |
56 |
* 1. Argument reduction: |
57 |
* Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658. |
58 |
* Given x, find r and integer k such that |
59 |
* |
60 |
* x = k*ln2 + r, |r| <= 0.5*ln2. |
61 |
* |
62 |
* Here r will be represented as r = hi-lo for better |
63 |
* accuracy. |
64 |
* |
65 |
* 2. Approximation of exp(r) by a special rational function on |
66 |
* the interval [0,0.34658]: |
67 |
* Write |
68 |
* R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ... |
69 |
* We use a special Reme algorithm on [0,0.34658] to generate |
70 |
* a polynomial of degree 5 to approximate R. The maximum error |
71 |
* of this polynomial approximation is bounded by 2**-59. In |
72 |
* other words, |
73 |
* R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5 |
74 |
* (where z=r*r, and the values of P1 to P5 are listed below) |
75 |
* and |
76 |
* | 5 | -59 |
77 |
* | 2.0+P1*z+...+P5*z - R(z) | <= 2 |
78 |
* | | |
79 |
* The computation of exp(r) thus becomes |
80 |
* 2*r |
81 |
* exp(r) = 1 + ------- |
82 |
* R - r |
83 |
* r*R1(r) |
84 |
* = 1 + r + ----------- (for better accuracy) |
85 |
* 2 - R1(r) |
86 |
* where |
87 |
* 2 4 10 |
88 |
* R1(r) = r - (P1*r + P2*r + ... + P5*r ). |
89 |
* |
90 |
* 3. Scale back to obtain exp(x): |
91 |
* From step 1, we have |
92 |
* exp(x) = 2^k * exp(r) |
93 |
* |
94 |
* Special cases: |
95 |
* exp(INF) is INF, exp(NaN) is NaN; |
96 |
* exp(-INF) is 0, and |
97 |
* for finite argument, only exp(0)=1 is exact. |
98 |
* |
99 |
* Accuracy: |
100 |
* according to an error analysis, the error is always less than |
101 |
* 1 ulp (unit in the last place). |
102 |
* |
103 |
* Misc. info. |
104 |
* For IEEE double |
105 |
* if x > 7.09782712893383973096e+02 then exp(x) overflow |
106 |
* if x < -7.45133219101941108420e+02 then exp(x) underflow |
107 |
* |
108 |
* Constants: |
109 |
* The hexadecimal values are the intended ones for the following |
110 |
* constants. The decimal values may be used, provided that the |
111 |
* compiler will convert from decimal to binary accurately enough |
112 |
* to produce the hexadecimal values shown. |
113 |
*/ |
114 |
|
115 |
#include "fdlibm.h" |
116 |
|
117 |
#ifdef __STDC__ |
118 |
static const double |
119 |
#else |
120 |
static double |
121 |
#endif |
122 |
one = 1.0, |
123 |
halF[2] = {0.5,-0.5,}, |
124 |
really_big = 1.0e+300, |
125 |
twom1000= 9.33263618503218878990e-302, /* 2**-1000=0x01700000,0*/ |
126 |
o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */ |
127 |
u_threshold= -7.45133219101941108420e+02, /* 0xc0874910, 0xD52D3051 */ |
128 |
ln2HI[2] ={ 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */ |
129 |
-6.93147180369123816490e-01,},/* 0xbfe62e42, 0xfee00000 */ |
130 |
ln2LO[2] ={ 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */ |
131 |
-1.90821492927058770002e-10,},/* 0xbdea39ef, 0x35793c76 */ |
132 |
invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */ |
133 |
P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ |
134 |
P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ |
135 |
P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ |
136 |
P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ |
137 |
P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */ |
138 |
|
139 |
|
140 |
#ifdef __STDC__ |
141 |
double __ieee754_exp(double x) /* default IEEE double exp */ |
142 |
#else |
143 |
double __ieee754_exp(x) /* default IEEE double exp */ |
144 |
double x; |
145 |
#endif |
146 |
{ |
147 |
fd_twoints u; |
148 |
double y,hi,lo,c,t; |
149 |
int k, xsb; |
150 |
unsigned hx; |
151 |
|
152 |
u.d = x; |
153 |
hx = __HI(u); /* high word of x */ |
154 |
xsb = (hx>>31)&1; /* sign bit of x */ |
155 |
hx &= 0x7fffffff; /* high word of |x| */ |
156 |
|
157 |
/* filter out non-finite argument */ |
158 |
if(hx >= 0x40862E42) { /* if |x|>=709.78... */ |
159 |
if(hx>=0x7ff00000) { |
160 |
u.d = x; |
161 |
if(((hx&0xfffff)|__LO(u))!=0) |
162 |
return x+x; /* NaN */ |
163 |
else return (xsb==0)? x:0.0; /* exp(+-inf)={inf,0} */ |
164 |
} |
165 |
if(x > o_threshold) return really_big*really_big; /* overflow */ |
166 |
if(x < u_threshold) return twom1000*twom1000; /* underflow */ |
167 |
} |
168 |
|
169 |
/* argument reduction */ |
170 |
if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ |
171 |
if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */ |
172 |
hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb; |
173 |
} else { |
174 |
k = (int)(invln2*x+halF[xsb]); |
175 |
t = k; |
176 |
hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */ |
177 |
lo = t*ln2LO[0]; |
178 |
} |
179 |
x = hi - lo; |
180 |
} |
181 |
else if(hx < 0x3e300000) { /* when |x|<2**-28 */ |
182 |
if(really_big+x>one) return one+x;/* trigger inexact */ |
183 |
} |
184 |
else k = 0; |
185 |
|
186 |
/* x is now in primary range */ |
187 |
t = x*x; |
188 |
c = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); |
189 |
if(k==0) return one-((x*c)/(c-2.0)-x); |
190 |
else y = one-((lo-(x*c)/(2.0-c))-hi); |
191 |
if(k >= -1021) { |
192 |
u.d = y; |
193 |
__HI(u) += (k<<20); /* add k to y's exponent */ |
194 |
y = u.d; |
195 |
return y; |
196 |
} else { |
197 |
u.d = y; |
198 |
__HI(u) += ((k+1000)<<20);/* add k to y's exponent */ |
199 |
y = u.d; |
200 |
return y*twom1000; |
201 |
} |
202 |
} |