1 |
siliconforks |
2 |
/* -*- 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 |
|
|
} |