Update copyright notices with scripts/update-copyrights.
[jlayton/glibc.git] / sysdeps / ieee754 / dbl-64 / e_pow.c
1 /*
2  * IBM Accurate Mathematical Library
3  * written by International Business Machines Corp.
4  * Copyright (C) 2001-2013 Free Software Foundation, Inc.
5  *
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.
10  *
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.
15  *
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/>.
18  */
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>
45
46 #ifndef SECTION
47 # define SECTION
48 #endif
49
50 static const double huge = 1.0e300, tiny = 1.0e-300;
51
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);
58
59 /***************************************************************************/
60 /* An ultimate power routine. Given two IEEE double machine numbers y,x    */
61 /* it computes the correctly rounded (to nearest) value of X^y.            */
62 /***************************************************************************/
63 double
64 SECTION
65 __ieee754_pow(double x, double y) {
66   double z,a,aa,error, t,a1,a2,y1,y2;
67 #if 0
68   double gor=1.0;
69 #endif
70   mynumber u,v;
71   int k;
72   int4 qx,qy;
73   v.x=y;
74   u.x=x;
75   if (v.i[LOW_HALF] == 0) { /* of y */
76     qx = u.i[HIGH_HALF]&0x7fffffff;
77     /* Checking  if x is not too small to compute */
78     if (((qx==0x7ff00000)&&(u.i[LOW_HALF]!=0))||(qx>0x7ff00000)) return NaNQ.x;
79     if (y == 1.0) return x;
80     if (y == 2.0) return x*x;
81     if (y == -1.0) return 1.0/x;
82     if (y == 0) return 1.0;
83   }
84   /* else */
85   if(((u.i[HIGH_HALF]>0 && u.i[HIGH_HALF]<0x7ff00000)||        /* x>0 and not x->0 */
86        (u.i[HIGH_HALF]==0 && u.i[LOW_HALF]!=0))  &&
87                                       /*   2^-1023< x<= 2^-1023 * 0x1.0000ffffffff */
88       (v.i[HIGH_HALF]&0x7fffffff) < 0x4ff00000) {              /* if y<-1 or y>1   */
89     double retval;
90
91     SET_RESTORE_ROUND (FE_TONEAREST);
92
93     /* Avoid internal underflow for tiny y.  The exact value of y does
94        not matter if |y| <= 2**-64.  */
95     if (ABS (y) < 0x1p-64)
96       y = y < 0 ? -0x1p-64 : 0x1p-64;
97     z = log1(x,&aa,&error);                                 /* x^y  =e^(y log (X)) */
98     t = y*CN;
99     y1 = t - (t-y);
100     y2 = y - y1;
101     t = z*CN;
102     a1 = t - (t-z);
103     a2 = (z - a1)+aa;
104     a = y1*a1;
105     aa = y2*a1 + y*a2;
106     a1 = a+aa;
107     a2 = (a-a1)+aa;
108     error = error*ABS(y);
109     t = __exp1(a1,a2,1.9e16*error);     /* return -10 or 0 if wasn't computed exactly */
110     retval = (t>0)?t:power1(x,y);
111
112     return retval;
113   }
114
115   if (x == 0) {
116     if (((v.i[HIGH_HALF] & 0x7fffffff) == 0x7ff00000 && v.i[LOW_HALF] != 0)
117         || (v.i[HIGH_HALF] & 0x7fffffff) > 0x7ff00000)
118       return y;
119     if (ABS(y) > 1.0e20) return (y>0)?0:1.0/0.0;
120     k = checkint(y);
121     if (k == -1)
122       return y < 0 ? 1.0/x : x;
123     else
124       return y < 0 ? 1.0/0.0 : 0.0;                               /* return 0 */
125   }
126
127   qx = u.i[HIGH_HALF]&0x7fffffff;  /*   no sign   */
128   qy = v.i[HIGH_HALF]&0x7fffffff;  /*   no sign   */
129
130   if (qx >= 0x7ff00000 && (qx > 0x7ff00000 || u.i[LOW_HALF] != 0)) return NaNQ.x;
131   if (qy >= 0x7ff00000 && (qy > 0x7ff00000 || v.i[LOW_HALF] != 0))
132     return x == 1.0 ? 1.0 : NaNQ.x;
133
134   /* if x<0 */
135   if (u.i[HIGH_HALF] < 0) {
136     k = checkint(y);
137     if (k==0) {
138       if (qy == 0x7ff00000) {
139         if (x == -1.0) return 1.0;
140         else if (x > -1.0) return v.i[HIGH_HALF] < 0 ? INF.x : 0.0;
141         else return v.i[HIGH_HALF] < 0 ? 0.0 : INF.x;
142       }
143       else if (qx == 0x7ff00000)
144         return y < 0 ? 0.0 : INF.x;
145       return NaNQ.x;                              /* y not integer and x<0 */
146     }
147     else if (qx == 0x7ff00000)
148       {
149         if (k < 0)
150           return y < 0 ? nZERO.x : nINF.x;
151         else
152           return y < 0 ? 0.0 : INF.x;
153       }
154     return (k==1)?__ieee754_pow(-x,y):-__ieee754_pow(-x,y); /* if y even or odd */
155   }
156   /* x>0 */
157
158   if (qx == 0x7ff00000)                              /* x= 2^-0x3ff */
159     {if (y == 0) return NaNQ.x;
160     return (y>0)?x:0; }
161
162   if (qy > 0x45f00000 && qy < 0x7ff00000) {
163     if (x == 1.0) return 1.0;
164     if (y>0) return (x>1.0)?huge*huge:tiny*tiny;
165     if (y<0) return (x<1.0)?huge*huge:tiny*tiny;
166   }
167
168   if (x == 1.0) return 1.0;
169   if (y>0) return (x>1.0)?INF.x:0;
170   if (y<0) return (x<1.0)?INF.x:0;
171   return 0;     /* unreachable, to make the compiler happy */
172 }
173 #ifndef __ieee754_pow
174 strong_alias (__ieee754_pow, __pow_finite)
175 #endif
176
177 /**************************************************************************/
178 /* Computing x^y using more accurate but more slow log routine            */
179 /**************************************************************************/
180 static double
181 SECTION
182 power1(double x, double y) {
183   double z,a,aa,error, t,a1,a2,y1,y2;
184   z = my_log2(x,&aa,&error);
185   t = y*CN;
186   y1 = t - (t-y);
187   y2 = y - y1;
188   t = z*CN;
189   a1 = t - (t-z);
190   a2 = z - a1;
191   a = y*z;
192   aa = ((y1*a1-a)+y1*a2+y2*a1)+y2*a2+aa*y;
193   a1 = a+aa;
194   a2 = (a-a1)+aa;
195   error = error*ABS(y);
196   t = __exp1(a1,a2,1.9e16*error);
197   return (t >= 0)?t:__slowpow(x,y,z);
198 }
199
200 /****************************************************************************/
201 /* Computing log(x) (x is left argument). The result is the returned double */
202 /* + the parameter delta.                                                   */
203 /* The result is bounded by error (rightmost argument)                      */
204 /****************************************************************************/
205 static double
206 SECTION
207 log1(double x, double *delta, double *error) {
208   int i,j,m;
209 #if 0
210   int n;
211 #endif
212   double uu,vv,eps,nx,e,e1,e2,t,t1,t2,res,add=0;
213 #if 0
214   double cor;
215 #endif
216   mynumber u,v;
217 #ifdef BIG_ENDI
218   mynumber
219 /**/ two52          = {{0x43300000, 0x00000000}}; /* 2**52         */
220 #else
221 #ifdef LITTLE_ENDI
222   mynumber
223 /**/ two52          = {{0x00000000, 0x43300000}}; /* 2**52         */
224 #endif
225 #endif
226
227   u.x = x;
228   m = u.i[HIGH_HALF];
229   *error = 0;
230   *delta = 0;
231   if (m < 0x00100000)             /*  1<x<2^-1007 */
232     { x = x*t52.x; add = -52.0; u.x = x; m = u.i[HIGH_HALF];}
233
234   if ((m&0x000fffff) < 0x0006a09e)
235     {u.i[HIGH_HALF] = (m&0x000fffff)|0x3ff00000; two52.i[LOW_HALF]=(m>>20); }
236   else
237     {u.i[HIGH_HALF] = (m&0x000fffff)|0x3fe00000; two52.i[LOW_HALF]=(m>>20)+1; }
238
239   v.x = u.x + bigu.x;
240   uu = v.x - bigu.x;
241   i = (v.i[LOW_HALF]&0x000003ff)<<2;
242   if (two52.i[LOW_HALF] == 1023)         /* nx = 0              */
243   {
244       if (i > 1192 && i < 1208)          /* |x-1| < 1.5*2**-10  */
245       {
246           t = x - 1.0;
247           t1 = (t+5.0e6)-5.0e6;
248           t2 = t-t1;
249           e1 = t - 0.5*t1*t1;
250           e2 = t*t*t*(r3+t*(r4+t*(r5+t*(r6+t*(r7+t*r8)))))-0.5*t2*(t+t1);
251           res = e1+e2;
252           *error = 1.0e-21*ABS(t);
253           *delta = (e1-res)+e2;
254           return res;
255       }                  /* |x-1| < 1.5*2**-10  */
256       else
257       {
258           v.x = u.x*(ui.x[i]+ui.x[i+1])+bigv.x;
259           vv = v.x-bigv.x;
260           j = v.i[LOW_HALF]&0x0007ffff;
261           j = j+j+j;
262           eps = u.x - uu*vv;
263           e1 = eps*ui.x[i];
264           e2 = eps*(ui.x[i+1]+vj.x[j]*(ui.x[i]+ui.x[i+1]));
265           e = e1+e2;
266           e2 =  ((e1-e)+e2);
267           t=ui.x[i+2]+vj.x[j+1];
268           t1 = t+e;
269           t2 = (((t-t1)+e)+(ui.x[i+3]+vj.x[j+2]))+e2+e*e*(p2+e*(p3+e*p4));
270           res=t1+t2;
271           *error = 1.0e-24;
272           *delta = (t1-res)+t2;
273           return res;
274       }
275   }   /* nx = 0 */
276   else                            /* nx != 0   */
277   {
278       eps = u.x - uu;
279       nx = (two52.x - two52e.x)+add;
280       e1 = eps*ui.x[i];
281       e2 = eps*ui.x[i+1];
282       e=e1+e2;
283       e2 = (e1-e)+e2;
284       t=nx*ln2a.x+ui.x[i+2];
285       t1=t+e;
286       t2=(((t-t1)+e)+nx*ln2b.x+ui.x[i+3]+e2)+e*e*(q2+e*(q3+e*(q4+e*(q5+e*q6))));
287       res = t1+t2;
288       *error = 1.0e-21;
289       *delta = (t1-res)+t2;
290       return res;
291   }                                /* nx != 0   */
292 }
293
294 /****************************************************************************/
295 /* More slow but more accurate routine of log                               */
296 /* Computing log(x)(x is left argument).The result is return double + delta.*/
297 /* The result is bounded by error (right argument)                           */
298 /****************************************************************************/
299 static double
300 SECTION
301 my_log2(double x, double *delta, double *error) {
302   int i,j,m;
303 #if 0
304   int n;
305 #endif
306   double uu,vv,eps,nx,e,e1,e2,t,t1,t2,res,add=0;
307 #if 0
308   double cor;
309 #endif
310   double ou1,ou2,lu1,lu2,ov,lv1,lv2,a,a1,a2;
311   double y,yy,z,zz,j1,j2,j7,j8;
312 #ifndef DLA_FMS
313   double j3,j4,j5,j6;
314 #endif
315   mynumber u,v;
316 #ifdef BIG_ENDI
317   mynumber
318 /**/ two52          = {{0x43300000, 0x00000000}}; /* 2**52         */
319 #else
320 #ifdef LITTLE_ENDI
321   mynumber
322 /**/ two52          = {{0x00000000, 0x43300000}}; /* 2**52         */
323 #endif
324 #endif
325
326   u.x = x;
327   m = u.i[HIGH_HALF];
328   *error = 0;
329   *delta = 0;
330   add=0;
331   if (m<0x00100000) {  /* x < 2^-1022 */
332     x = x*t52.x;  add = -52.0; u.x = x; m = u.i[HIGH_HALF]; }
333
334   if ((m&0x000fffff) < 0x0006a09e)
335     {u.i[HIGH_HALF] = (m&0x000fffff)|0x3ff00000; two52.i[LOW_HALF]=(m>>20); }
336   else
337     {u.i[HIGH_HALF] = (m&0x000fffff)|0x3fe00000; two52.i[LOW_HALF]=(m>>20)+1; }
338
339   v.x = u.x + bigu.x;
340   uu = v.x - bigu.x;
341   i = (v.i[LOW_HALF]&0x000003ff)<<2;
342   /*------------------------------------- |x-1| < 2**-11-------------------------------  */
343   if ((two52.i[LOW_HALF] == 1023)  && (i == 1200))
344   {
345       t = x - 1.0;
346       EMULV(t,s3,y,yy,j1,j2,j3,j4,j5);
347       ADD2(-0.5,0,y,yy,z,zz,j1,j2);
348       MUL2(t,0,z,zz,y,yy,j1,j2,j3,j4,j5,j6,j7,j8);
349       MUL2(t,0,y,yy,z,zz,j1,j2,j3,j4,j5,j6,j7,j8);
350
351       e1 = t+z;
352       e2 = (((t-e1)+z)+zz)+t*t*t*(ss3+t*(s4+t*(s5+t*(s6+t*(s7+t*s8)))));
353       res = e1+e2;
354       *error = 1.0e-25*ABS(t);
355       *delta = (e1-res)+e2;
356       return res;
357   }
358   /*----------------------------- |x-1| > 2**-11  --------------------------  */
359   else
360   {          /*Computing log(x) according to log table                        */
361       nx = (two52.x - two52e.x)+add;
362       ou1 = ui.x[i];
363       ou2 = ui.x[i+1];
364       lu1 = ui.x[i+2];
365       lu2 = ui.x[i+3];
366       v.x = u.x*(ou1+ou2)+bigv.x;
367       vv = v.x-bigv.x;
368       j = v.i[LOW_HALF]&0x0007ffff;
369       j = j+j+j;
370       eps = u.x - uu*vv;
371       ov  = vj.x[j];
372       lv1 = vj.x[j+1];
373       lv2 = vj.x[j+2];
374       a = (ou1+ou2)*(1.0+ov);
375       a1 = (a+1.0e10)-1.0e10;
376       a2 = a*(1.0-a1*uu*vv);
377       e1 = eps*a1;
378       e2 = eps*a2;
379       e = e1+e2;
380       e2 = (e1-e)+e2;
381       t=nx*ln2a.x+lu1+lv1;
382       t1 = t+e;
383       t2 = (((t-t1)+e)+(lu2+lv2+nx*ln2b.x+e2))+e*e*(p2+e*(p3+e*p4));
384       res=t1+t2;
385       *error = 1.0e-27;
386       *delta = (t1-res)+t2;
387       return res;
388   }
389 }
390
391 /**********************************************************************/
392 /* Routine receives a double x and checks if it is an integer. If not */
393 /* it returns 0, else it returns 1 if even or -1 if odd.              */
394 /**********************************************************************/
395 static int
396 SECTION
397 checkint(double x) {
398   union {int4 i[2]; double x;} u;
399   int k,m,n;
400 #if 0
401   int l;
402 #endif
403   u.x = x;
404   m = u.i[HIGH_HALF]&0x7fffffff;    /* no sign */
405   if (m >= 0x7ff00000) return 0;    /*  x is +/-inf or NaN  */
406   if (m >= 0x43400000) return 1;    /*  |x| >= 2**53   */
407   if (m < 0x40000000) return 0;     /* |x| < 2,  can not be 0 or 1  */
408   n = u.i[LOW_HALF];
409   k = (m>>20)-1023;                 /*  1 <= k <= 52   */
410   if (k == 52) return (n&1)? -1:1;  /* odd or even*/
411   if (k>20) {
412     if (n<<(k-20)) return 0;        /* if not integer */
413     return (n<<(k-21))?-1:1;
414   }
415   if (n) return 0;                  /*if  not integer*/
416   if (k == 20) return (m&1)? -1:1;
417   if (m<<(k+12)) return 0;
418   return (m<<(k+11))?-1:1;
419 }