Update copyright notices with scripts/update-copyrights
[glibc.git] / sysdeps / ieee754 / dbl-64 / e_pow.c
blob1c5f4b311e7f9f2858c34da89c420be9edbefac1
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: upow.c */
21 /* */
22 /* FUNCTIONS: upow */
23 /* power1 */
24 /* my_log2 */
25 /* log1 */
26 /* checkint */
27 /* FILES NEEDED: dla.h endian.h mpa.h mydefs.h */
28 /* halfulp.c mpexp.c mplog.c slowexp.c slowpow.c mpa.c */
29 /* uexp.c upow.c */
30 /* root.tbl uexp.tbl upow.tbl */
31 /* An ultimate power routine. Given two IEEE double machine numbers y,x */
32 /* it computes the correctly rounded (to nearest) value of x^y. */
33 /* Assumption: Machine arithmetic operations are performed in */
34 /* round to nearest mode of IEEE 754 standard. */
35 /* */
36 /***************************************************************************/
37 #include "endian.h"
38 #include "upow.h"
39 #include <dla.h>
40 #include "mydefs.h"
41 #include "MathLib.h"
42 #include "upow.tbl"
43 #include <math_private.h>
44 #include <fenv.h>
46 #ifndef SECTION
47 # define SECTION
48 #endif
50 static const double huge = 1.0e300, tiny = 1.0e-300;
52 double __exp1 (double x, double xx, double error);
53 static double log1 (double x, double *delta, double *error);
54 static double my_log2 (double x, double *delta, double *error);
55 double __slowpow (double x, double y, double z);
56 static double power1 (double x, double y);
57 static int checkint (double x);
59 /* An ultimate power routine. Given two IEEE double machine numbers y, x it
60 computes the correctly rounded (to nearest) value of X^y. */
61 double
62 SECTION
63 __ieee754_pow (double x, double y)
65 double z, a, aa, error, t, a1, a2, y1, y2;
66 mynumber u, v;
67 int k;
68 int4 qx, qy;
69 v.x = y;
70 u.x = x;
71 if (v.i[LOW_HALF] == 0)
72 { /* of y */
73 qx = u.i[HIGH_HALF] & 0x7fffffff;
74 /* Is x a NaN? */
75 if (((qx == 0x7ff00000) && (u.i[LOW_HALF] != 0)) || (qx > 0x7ff00000))
76 return x;
77 if (y == 1.0)
78 return x;
79 if (y == 2.0)
80 return x * x;
81 if (y == -1.0)
82 return 1.0 / x;
83 if (y == 0)
84 return 1.0;
86 /* else */
87 if (((u.i[HIGH_HALF] > 0 && u.i[HIGH_HALF] < 0x7ff00000) || /* x>0 and not x->0 */
88 (u.i[HIGH_HALF] == 0 && u.i[LOW_HALF] != 0)) &&
89 /* 2^-1023< x<= 2^-1023 * 0x1.0000ffffffff */
90 (v.i[HIGH_HALF] & 0x7fffffff) < 0x4ff00000)
91 { /* if y<-1 or y>1 */
92 double retval;
94 SET_RESTORE_ROUND (FE_TONEAREST);
96 /* Avoid internal underflow for tiny y. The exact value of y does
97 not matter if |y| <= 2**-64. */
98 if (ABS (y) < 0x1p-64)
99 y = y < 0 ? -0x1p-64 : 0x1p-64;
100 z = log1 (x, &aa, &error); /* x^y =e^(y log (X)) */
101 t = y * CN;
102 y1 = t - (t - y);
103 y2 = y - y1;
104 t = z * CN;
105 a1 = t - (t - z);
106 a2 = (z - a1) + aa;
107 a = y1 * a1;
108 aa = y2 * a1 + y * a2;
109 a1 = a + aa;
110 a2 = (a - a1) + aa;
111 error = error * ABS (y);
112 t = __exp1 (a1, a2, 1.9e16 * error); /* return -10 or 0 if wasn't computed exactly */
113 retval = (t > 0) ? t : power1 (x, y);
115 return retval;
118 if (x == 0)
120 if (((v.i[HIGH_HALF] & 0x7fffffff) == 0x7ff00000 && v.i[LOW_HALF] != 0)
121 || (v.i[HIGH_HALF] & 0x7fffffff) > 0x7ff00000) /* NaN */
122 return y;
123 if (ABS (y) > 1.0e20)
124 return (y > 0) ? 0 : 1.0 / 0.0;
125 k = checkint (y);
126 if (k == -1)
127 return y < 0 ? 1.0 / x : x;
128 else
129 return y < 0 ? 1.0 / 0.0 : 0.0; /* return 0 */
132 qx = u.i[HIGH_HALF] & 0x7fffffff; /* no sign */
133 qy = v.i[HIGH_HALF] & 0x7fffffff; /* no sign */
135 if (qx >= 0x7ff00000 && (qx > 0x7ff00000 || u.i[LOW_HALF] != 0)) /* NaN */
136 return x;
137 if (qy >= 0x7ff00000 && (qy > 0x7ff00000 || v.i[LOW_HALF] != 0)) /* NaN */
138 return x == 1.0 ? 1.0 : y;
140 /* if x<0 */
141 if (u.i[HIGH_HALF] < 0)
143 k = checkint (y);
144 if (k == 0)
146 if (qy == 0x7ff00000)
148 if (x == -1.0)
149 return 1.0;
150 else if (x > -1.0)
151 return v.i[HIGH_HALF] < 0 ? INF.x : 0.0;
152 else
153 return v.i[HIGH_HALF] < 0 ? 0.0 : INF.x;
155 else if (qx == 0x7ff00000)
156 return y < 0 ? 0.0 : INF.x;
157 return (x - x) / (x - x); /* y not integer and x<0 */
159 else if (qx == 0x7ff00000)
161 if (k < 0)
162 return y < 0 ? nZERO.x : nINF.x;
163 else
164 return y < 0 ? 0.0 : INF.x;
166 /* if y even or odd */
167 return (k == 1) ? __ieee754_pow (-x, y) : -__ieee754_pow (-x, y);
169 /* x>0 */
171 if (qx == 0x7ff00000) /* x= 2^-0x3ff */
172 return y > 0 ? x : 0;
174 if (qy > 0x45f00000 && qy < 0x7ff00000)
176 if (x == 1.0)
177 return 1.0;
178 if (y > 0)
179 return (x > 1.0) ? huge * huge : tiny * tiny;
180 if (y < 0)
181 return (x < 1.0) ? huge * huge : tiny * tiny;
184 if (x == 1.0)
185 return 1.0;
186 if (y > 0)
187 return (x > 1.0) ? INF.x : 0;
188 if (y < 0)
189 return (x < 1.0) ? INF.x : 0;
190 return 0; /* unreachable, to make the compiler happy */
193 #ifndef __ieee754_pow
194 strong_alias (__ieee754_pow, __pow_finite)
195 #endif
197 /* Compute x^y using more accurate but more slow log routine. */
198 static double
199 SECTION
200 power1 (double x, double y)
202 double z, a, aa, error, t, a1, a2, y1, y2;
203 z = my_log2 (x, &aa, &error);
204 t = y * CN;
205 y1 = t - (t - y);
206 y2 = y - y1;
207 t = z * CN;
208 a1 = t - (t - z);
209 a2 = z - a1;
210 a = y * z;
211 aa = ((y1 * a1 - a) + y1 * a2 + y2 * a1) + y2 * a2 + aa * y;
212 a1 = a + aa;
213 a2 = (a - a1) + aa;
214 error = error * ABS (y);
215 t = __exp1 (a1, a2, 1.9e16 * error);
216 return (t >= 0) ? t : __slowpow (x, y, z);
219 /* Compute log(x) (x is left argument). The result is the returned double + the
220 parameter DELTA. The result is bounded by ERROR. */
221 static double
222 SECTION
223 log1 (double x, double *delta, double *error)
225 int i, j, m;
226 double uu, vv, eps, nx, e, e1, e2, t, t1, t2, res, add = 0;
227 mynumber u, v;
228 #ifdef BIG_ENDI
229 mynumber /**/ two52 = {{0x43300000, 0x00000000}}; /* 2**52 */
230 #else
231 # ifdef LITTLE_ENDI
232 mynumber /**/ two52 = {{0x00000000, 0x43300000}}; /* 2**52 */
233 # endif
234 #endif
236 u.x = x;
237 m = u.i[HIGH_HALF];
238 *error = 0;
239 *delta = 0;
240 if (m < 0x00100000) /* 1<x<2^-1007 */
242 x = x * t52.x;
243 add = -52.0;
244 u.x = x;
245 m = u.i[HIGH_HALF];
248 if ((m & 0x000fffff) < 0x0006a09e)
250 u.i[HIGH_HALF] = (m & 0x000fffff) | 0x3ff00000;
251 two52.i[LOW_HALF] = (m >> 20);
253 else
255 u.i[HIGH_HALF] = (m & 0x000fffff) | 0x3fe00000;
256 two52.i[LOW_HALF] = (m >> 20) + 1;
259 v.x = u.x + bigu.x;
260 uu = v.x - bigu.x;
261 i = (v.i[LOW_HALF] & 0x000003ff) << 2;
262 if (two52.i[LOW_HALF] == 1023) /* nx = 0 */
264 if (i > 1192 && i < 1208) /* |x-1| < 1.5*2**-10 */
266 t = x - 1.0;
267 t1 = (t + 5.0e6) - 5.0e6;
268 t2 = t - t1;
269 e1 = t - 0.5 * t1 * t1;
270 e2 = (t * t * t * (r3 + t * (r4 + t * (r5 + t * (r6 + t
271 * (r7 + t * r8)))))
272 - 0.5 * t2 * (t + t1));
273 res = e1 + e2;
274 *error = 1.0e-21 * ABS (t);
275 *delta = (e1 - res) + e2;
276 return res;
277 } /* |x-1| < 1.5*2**-10 */
278 else
280 v.x = u.x * (ui.x[i] + ui.x[i + 1]) + bigv.x;
281 vv = v.x - bigv.x;
282 j = v.i[LOW_HALF] & 0x0007ffff;
283 j = j + j + j;
284 eps = u.x - uu * vv;
285 e1 = eps * ui.x[i];
286 e2 = eps * (ui.x[i + 1] + vj.x[j] * (ui.x[i] + ui.x[i + 1]));
287 e = e1 + e2;
288 e2 = ((e1 - e) + e2);
289 t = ui.x[i + 2] + vj.x[j + 1];
290 t1 = t + e;
291 t2 = ((((t - t1) + e) + (ui.x[i + 3] + vj.x[j + 2])) + e2 + e * e
292 * (p2 + e * (p3 + e * p4)));
293 res = t1 + t2;
294 *error = 1.0e-24;
295 *delta = (t1 - res) + t2;
296 return res;
298 } /* nx = 0 */
299 else /* nx != 0 */
301 eps = u.x - uu;
302 nx = (two52.x - two52e.x) + add;
303 e1 = eps * ui.x[i];
304 e2 = eps * ui.x[i + 1];
305 e = e1 + e2;
306 e2 = (e1 - e) + e2;
307 t = nx * ln2a.x + ui.x[i + 2];
308 t1 = t + e;
309 t2 = ((((t - t1) + e) + nx * ln2b.x + ui.x[i + 3] + e2) + e * e
310 * (q2 + e * (q3 + e * (q4 + e * (q5 + e * q6)))));
311 res = t1 + t2;
312 *error = 1.0e-21;
313 *delta = (t1 - res) + t2;
314 return res;
315 } /* nx != 0 */
318 /* Slower but more accurate routine of log. The returned result is double +
319 DELTA. The result is bounded by ERROR. */
320 static double
321 SECTION
322 my_log2 (double x, double *delta, double *error)
324 int i, j, m;
325 double uu, vv, eps, nx, e, e1, e2, t, t1, t2, res, add = 0;
326 double ou1, ou2, lu1, lu2, ov, lv1, lv2, a, a1, a2;
327 double y, yy, z, zz, j1, j2, j7, j8;
328 #ifndef DLA_FMS
329 double j3, j4, j5, j6;
330 #endif
331 mynumber u, v;
332 #ifdef BIG_ENDI
333 mynumber /**/ two52 = {{0x43300000, 0x00000000}}; /* 2**52 */
334 #else
335 # ifdef LITTLE_ENDI
336 mynumber /**/ two52 = {{0x00000000, 0x43300000}}; /* 2**52 */
337 # endif
338 #endif
340 u.x = x;
341 m = u.i[HIGH_HALF];
342 *error = 0;
343 *delta = 0;
344 add = 0;
345 if (m < 0x00100000)
346 { /* x < 2^-1022 */
347 x = x * t52.x;
348 add = -52.0;
349 u.x = x;
350 m = u.i[HIGH_HALF];
353 if ((m & 0x000fffff) < 0x0006a09e)
355 u.i[HIGH_HALF] = (m & 0x000fffff) | 0x3ff00000;
356 two52.i[LOW_HALF] = (m >> 20);
358 else
360 u.i[HIGH_HALF] = (m & 0x000fffff) | 0x3fe00000;
361 two52.i[LOW_HALF] = (m >> 20) + 1;
364 v.x = u.x + bigu.x;
365 uu = v.x - bigu.x;
366 i = (v.i[LOW_HALF] & 0x000003ff) << 2;
367 /*------------------------------------- |x-1| < 2**-11------------------------------- */
368 if ((two52.i[LOW_HALF] == 1023) && (i == 1200))
370 t = x - 1.0;
371 EMULV (t, s3, y, yy, j1, j2, j3, j4, j5);
372 ADD2 (-0.5, 0, y, yy, z, zz, j1, j2);
373 MUL2 (t, 0, z, zz, y, yy, j1, j2, j3, j4, j5, j6, j7, j8);
374 MUL2 (t, 0, y, yy, z, zz, j1, j2, j3, j4, j5, j6, j7, j8);
376 e1 = t + z;
377 e2 = ((((t - e1) + z) + zz) + t * t * t
378 * (ss3 + t * (s4 + t * (s5 + t * (s6 + t * (s7 + t * s8))))));
379 res = e1 + e2;
380 *error = 1.0e-25 * ABS (t);
381 *delta = (e1 - res) + e2;
382 return res;
384 /*----------------------------- |x-1| > 2**-11 -------------------------- */
385 else
386 { /*Computing log(x) according to log table */
387 nx = (two52.x - two52e.x) + add;
388 ou1 = ui.x[i];
389 ou2 = ui.x[i + 1];
390 lu1 = ui.x[i + 2];
391 lu2 = ui.x[i + 3];
392 v.x = u.x * (ou1 + ou2) + bigv.x;
393 vv = v.x - bigv.x;
394 j = v.i[LOW_HALF] & 0x0007ffff;
395 j = j + j + j;
396 eps = u.x - uu * vv;
397 ov = vj.x[j];
398 lv1 = vj.x[j + 1];
399 lv2 = vj.x[j + 2];
400 a = (ou1 + ou2) * (1.0 + ov);
401 a1 = (a + 1.0e10) - 1.0e10;
402 a2 = a * (1.0 - a1 * uu * vv);
403 e1 = eps * a1;
404 e2 = eps * a2;
405 e = e1 + e2;
406 e2 = (e1 - e) + e2;
407 t = nx * ln2a.x + lu1 + lv1;
408 t1 = t + e;
409 t2 = ((((t - t1) + e) + (lu2 + lv2 + nx * ln2b.x + e2)) + e * e
410 * (p2 + e * (p3 + e * p4)));
411 res = t1 + t2;
412 *error = 1.0e-27;
413 *delta = (t1 - res) + t2;
414 return res;
418 /* This function receives a double x and checks if it is an integer. If not,
419 it returns 0, else it returns 1 if even or -1 if odd. */
420 static int
421 SECTION
422 checkint (double x)
424 union
426 int4 i[2];
427 double x;
428 } u;
429 int k, m, n;
430 u.x = x;
431 m = u.i[HIGH_HALF] & 0x7fffffff; /* no sign */
432 if (m >= 0x7ff00000)
433 return 0; /* x is +/-inf or NaN */
434 if (m >= 0x43400000)
435 return 1; /* |x| >= 2**53 */
436 if (m < 0x40000000)
437 return 0; /* |x| < 2, can not be 0 or 1 */
438 n = u.i[LOW_HALF];
439 k = (m >> 20) - 1023; /* 1 <= k <= 52 */
440 if (k == 52)
441 return (n & 1) ? -1 : 1; /* odd or even */
442 if (k > 20)
444 if (n << (k - 20))
445 return 0; /* if not integer */
446 return (n << (k - 21)) ? -1 : 1;
448 if (n)
449 return 0; /*if not integer */
450 if (k == 20)
451 return (m & 1) ? -1 : 1;
452 if (m << (k + 12))
453 return 0;
454 return (m << (k + 11)) ? -1 : 1;