Update copyright notices with scripts/update-copyrights
[glibc.git] / sysdeps / ieee754 / dbl-64 / e_exp.c
blob100fc397a7d9700905098e6bbc98258df4b4a3a8
1 /*
2 * IBM Accurate Mathematical Library
3 * written by International Business Machines Corp.
4 * Copyright (C) 2001-2014 Free Software Foundation, Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 /***************************************************************************/
20 /* MODULE_NAME:uexp.c */
21 /* */
22 /* FUNCTION:uexp */
23 /* exp1 */
24 /* */
25 /* FILES NEEDED:dla.h endian.h mpa.h mydefs.h uexp.h */
26 /* mpa.c mpexp.x slowexp.c */
27 /* */
28 /* An ultimate exp routine. Given an IEEE double machine number x */
29 /* it computes the correctly rounded (to nearest) value of e^x */
30 /* Assumption: Machine arithmetic operations are performed in */
31 /* round to nearest mode of IEEE 754 standard. */
32 /* */
33 /***************************************************************************/
35 #include "endian.h"
36 #include "uexp.h"
37 #include "mydefs.h"
38 #include "MathLib.h"
39 #include "uexp.tbl"
40 #include <math_private.h>
41 #include <fenv.h>
42 #include <float.h>
44 #ifndef SECTION
45 # define SECTION
46 #endif
48 double __slowexp (double);
50 /* An ultimate exp routine. Given an IEEE double machine number x it computes
51 the correctly rounded (to nearest) value of e^x. */
52 double
53 SECTION
54 __ieee754_exp (double x)
56 double bexp, t, eps, del, base, y, al, bet, res, rem, cor;
57 mynumber junk1, junk2, binexp = {{0, 0}};
58 int4 i, j, m, n, ex;
59 double retval;
61 SET_RESTORE_ROUND (FE_TONEAREST);
63 junk1.x = x;
64 m = junk1.i[HIGH_HALF];
65 n = m & hugeint;
67 if (n > smallint && n < bigint)
69 y = x * log2e.x + three51.x;
70 bexp = y - three51.x; /* multiply the result by 2**bexp */
72 junk1.x = y;
74 eps = bexp * ln_two2.x; /* x = bexp*ln(2) + t - eps */
75 t = x - bexp * ln_two1.x;
77 y = t + three33.x;
78 base = y - three33.x; /* t rounded to a multiple of 2**-18 */
79 junk2.x = y;
80 del = (t - base) - eps; /* x = bexp*ln(2) + base + del */
81 eps = del + del * del * (p3.x * del + p2.x);
83 binexp.i[HIGH_HALF] = (junk1.i[LOW_HALF] + 1023) << 20;
85 i = ((junk2.i[LOW_HALF] >> 8) & 0xfffffffe) + 356;
86 j = (junk2.i[LOW_HALF] & 511) << 1;
88 al = coar.x[i] * fine.x[j];
89 bet = ((coar.x[i] * fine.x[j + 1] + coar.x[i + 1] * fine.x[j])
90 + coar.x[i + 1] * fine.x[j + 1]);
92 rem = (bet + bet * eps) + al * eps;
93 res = al + rem;
94 cor = (al - res) + rem;
95 if (res == (res + cor * err_0))
97 retval = res * binexp.x;
98 goto ret;
100 else
102 retval = __slowexp (x);
103 goto ret;
104 } /*if error is over bound */
107 if (n <= smallint)
109 retval = 1.0;
110 goto ret;
113 if (n >= badint)
115 if (n > infint)
117 retval = x + x;
118 goto ret;
119 } /* x is NaN */
120 if (n < infint)
122 retval = (x > 0) ? (hhuge * hhuge) : (tiny * tiny);
123 goto ret;
125 /* x is finite, cause either overflow or underflow */
126 if (junk1.i[LOW_HALF] != 0)
128 retval = x + x;
129 goto ret;
130 } /* x is NaN */
131 retval = (x > 0) ? inf.x : zero; /* |x| = inf; return either inf or 0 */
132 goto ret;
135 y = x * log2e.x + three51.x;
136 bexp = y - three51.x;
137 junk1.x = y;
138 eps = bexp * ln_two2.x;
139 t = x - bexp * ln_two1.x;
140 y = t + three33.x;
141 base = y - three33.x;
142 junk2.x = y;
143 del = (t - base) - eps;
144 eps = del + del * del * (p3.x * del + p2.x);
145 i = ((junk2.i[LOW_HALF] >> 8) & 0xfffffffe) + 356;
146 j = (junk2.i[LOW_HALF] & 511) << 1;
147 al = coar.x[i] * fine.x[j];
148 bet = ((coar.x[i] * fine.x[j + 1] + coar.x[i + 1] * fine.x[j])
149 + coar.x[i + 1] * fine.x[j + 1]);
150 rem = (bet + bet * eps) + al * eps;
151 res = al + rem;
152 cor = (al - res) + rem;
153 if (m >> 31)
155 ex = junk1.i[LOW_HALF];
156 if (res < 1.0)
158 res += res;
159 cor += cor;
160 ex -= 1;
162 if (ex >= -1022)
164 binexp.i[HIGH_HALF] = (1023 + ex) << 20;
165 if (res == (res + cor * err_0))
167 retval = res * binexp.x;
168 goto ret;
170 else
172 retval = __slowexp (x);
173 goto check_uflow_ret;
174 } /*if error is over bound */
176 ex = -(1022 + ex);
177 binexp.i[HIGH_HALF] = (1023 - ex) << 20;
178 res *= binexp.x;
179 cor *= binexp.x;
180 eps = 1.0000000001 + err_0 * binexp.x;
181 t = 1.0 + res;
182 y = ((1.0 - t) + res) + cor;
183 res = t + y;
184 cor = (t - res) + y;
185 if (res == (res + eps * cor))
187 binexp.i[HIGH_HALF] = 0x00100000;
188 retval = (res - 1.0) * binexp.x;
189 goto check_uflow_ret;
191 else
193 retval = __slowexp (x);
194 goto check_uflow_ret;
195 } /* if error is over bound */
196 check_uflow_ret:
197 if (retval < DBL_MIN)
199 #if FLT_EVAL_METHOD != 0
200 volatile
201 #endif
202 double force_underflow = tiny * tiny;
203 math_force_eval (force_underflow);
205 goto ret;
207 else
209 binexp.i[HIGH_HALF] = (junk1.i[LOW_HALF] + 767) << 20;
210 if (res == (res + cor * err_0))
212 retval = res * binexp.x * t256.x;
213 goto ret;
215 else
217 retval = __slowexp (x);
218 goto ret;
221 ret:
222 return retval;
224 #ifndef __ieee754_exp
225 strong_alias (__ieee754_exp, __exp_finite)
226 #endif
228 /* Compute e^(x+xx). The routine also receives bound of error of previous
229 calculation. If after computing exp the error exceeds the allowed bounds,
230 the routine returns a non-positive number. Otherwise it returns the
231 computed result, which is always positive. */
232 double
233 SECTION
234 __exp1 (double x, double xx, double error)
236 double bexp, t, eps, del, base, y, al, bet, res, rem, cor;
237 mynumber junk1, junk2, binexp = {{0, 0}};
238 int4 i, j, m, n, ex;
240 junk1.x = x;
241 m = junk1.i[HIGH_HALF];
242 n = m & hugeint; /* no sign */
244 if (n > smallint && n < bigint)
246 y = x * log2e.x + three51.x;
247 bexp = y - three51.x; /* multiply the result by 2**bexp */
249 junk1.x = y;
251 eps = bexp * ln_two2.x; /* x = bexp*ln(2) + t - eps */
252 t = x - bexp * ln_two1.x;
254 y = t + three33.x;
255 base = y - three33.x; /* t rounded to a multiple of 2**-18 */
256 junk2.x = y;
257 del = (t - base) + (xx - eps); /* x = bexp*ln(2) + base + del */
258 eps = del + del * del * (p3.x * del + p2.x);
260 binexp.i[HIGH_HALF] = (junk1.i[LOW_HALF] + 1023) << 20;
262 i = ((junk2.i[LOW_HALF] >> 8) & 0xfffffffe) + 356;
263 j = (junk2.i[LOW_HALF] & 511) << 1;
265 al = coar.x[i] * fine.x[j];
266 bet = ((coar.x[i] * fine.x[j + 1] + coar.x[i + 1] * fine.x[j])
267 + coar.x[i + 1] * fine.x[j + 1]);
269 rem = (bet + bet * eps) + al * eps;
270 res = al + rem;
271 cor = (al - res) + rem;
272 if (res == (res + cor * (1.0 + error + err_1)))
273 return res * binexp.x;
274 else
275 return -10.0;
278 if (n <= smallint)
279 return 1.0; /* if x->0 e^x=1 */
281 if (n >= badint)
283 if (n > infint)
284 return (zero / zero); /* x is NaN, return invalid */
285 if (n < infint)
286 return ((x > 0) ? (hhuge * hhuge) : (tiny * tiny));
287 /* x is finite, cause either overflow or underflow */
288 if (junk1.i[LOW_HALF] != 0)
289 return (zero / zero); /* x is NaN */
290 return ((x > 0) ? inf.x : zero); /* |x| = inf; return either inf or 0 */
293 y = x * log2e.x + three51.x;
294 bexp = y - three51.x;
295 junk1.x = y;
296 eps = bexp * ln_two2.x;
297 t = x - bexp * ln_two1.x;
298 y = t + three33.x;
299 base = y - three33.x;
300 junk2.x = y;
301 del = (t - base) + (xx - eps);
302 eps = del + del * del * (p3.x * del + p2.x);
303 i = ((junk2.i[LOW_HALF] >> 8) & 0xfffffffe) + 356;
304 j = (junk2.i[LOW_HALF] & 511) << 1;
305 al = coar.x[i] * fine.x[j];
306 bet = ((coar.x[i] * fine.x[j + 1] + coar.x[i + 1] * fine.x[j])
307 + coar.x[i + 1] * fine.x[j + 1]);
308 rem = (bet + bet * eps) + al * eps;
309 res = al + rem;
310 cor = (al - res) + rem;
311 if (m >> 31)
313 ex = junk1.i[LOW_HALF];
314 if (res < 1.0)
316 res += res;
317 cor += cor;
318 ex -= 1;
320 if (ex >= -1022)
322 binexp.i[HIGH_HALF] = (1023 + ex) << 20;
323 if (res == (res + cor * (1.0 + error + err_1)))
324 return res * binexp.x;
325 else
326 return -10.0;
328 ex = -(1022 + ex);
329 binexp.i[HIGH_HALF] = (1023 - ex) << 20;
330 res *= binexp.x;
331 cor *= binexp.x;
332 eps = 1.00000000001 + (error + err_1) * binexp.x;
333 t = 1.0 + res;
334 y = ((1.0 - t) + res) + cor;
335 res = t + y;
336 cor = (t - res) + y;
337 if (res == (res + eps * cor))
339 binexp.i[HIGH_HALF] = 0x00100000;
340 return (res - 1.0) * binexp.x;
342 else
343 return -10.0;
345 else
347 binexp.i[HIGH_HALF] = (junk1.i[LOW_HALF] + 767) << 20;
348 if (res == (res + cor * (1.0 + error + err_1)))
349 return res * binexp.x * t256.x;
350 else
351 return -10.0;