summaryrefslogtreecommitdiff
path: root/sysdeps/ieee754/dbl-64/e_pow.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2001-03-13 02:01:34 +0000
committerUlrich Drepper <drepper@redhat.com>2001-03-13 02:01:34 +0000
commitca58f1dbeb62840dad345d6bfcca18c81db130a8 (patch)
treeeb1b9705fc324e0852875514dda109641e9399de /sysdeps/ieee754/dbl-64/e_pow.c
parent9a656848eaa2f9c96ce438eeb3c63e33933c0b2e (diff)
downloadglibc-ca58f1dbeb62840dad345d6bfcca18c81db130a8.tar.gz
Update.
2001-03-12 Ulrich Drepper <drepper@redhat.com> * sysdeps/ieee754/dbl-64/e_remainder.c: Fix handling of boundary conditions. * sysdeps/ieee754/dbl-64/e_pow.c: Fix handling of boundary conditions. * sysdeps/ieee754/dbl-64/s_sin.c (__sin): Handle Inf and NaN correctly. (__cos): Likewise. * sysdeps/ieee754/dbl-64/e_asin.c (__ieee754_asin): Handle NaN correctly. (__ieee754_acos): Likewise. redefinition. * sysdeps/ieee754/dbl-64/endian.h: Define also one of BIG_ENDI and LITTLE_ENDI. * sysdeps/ieee754/dbl-64/MathLib.h (Init_Lib): Use void as parameter list.
Diffstat (limited to 'sysdeps/ieee754/dbl-64/e_pow.c')
-rw-r--r--sysdeps/ieee754/dbl-64/e_pow.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/sysdeps/ieee754/dbl-64/e_pow.c b/sysdeps/ieee754/dbl-64/e_pow.c
index cd6f27f33e..dc92922d18 100644
--- a/sysdeps/ieee754/dbl-64/e_pow.c
+++ b/sysdeps/ieee754/dbl-64/e_pow.c
@@ -45,7 +45,7 @@
double __exp1(double x, double xx, double error);
static double log1(double x, double *delta, double *error);
static double log2(double x, double *delta, double *error);
-double slowpow(double x, double y,double z);
+double __slowpow(double x, double y,double z);
static double power1(double x, double y);
static int checkint(double x);
@@ -69,8 +69,8 @@ double __ieee754_pow(double x, double y) {
if (((qx==0x7ff00000)&&(u.i[LOW_HALF]!=0))||(qx>0x7ff00000)) return NaNQ.x;
if (y == 1.0) return x;
if (y == 2.0) return x*x;
- if (y == -1.0) return (x!=0)?1.0/x:NaNQ.x;
- if (y == 0) return ((x>0)&&(qx<0x7ff00000))?1.0:NaNQ.x;
+ if (y == -1.0) return 1.0/x;
+ if (y == 0) return 1.0;
}
/* else */
if(((u.i[HIGH_HALF]>0 && u.i[HIGH_HALF]<0x7ff00000)|| /* x>0 and not x->0 */
@@ -94,16 +94,37 @@ double __ieee754_pow(double x, double y) {
}
if (x == 0) {
- if (ABS(y) > 1.0e20) return (y>0)?0:NaNQ.x;
+ if (((v.i[HIGH_HALF] & 0x7fffffff) == 0x7ff00000 && v.i[LOW_HALF] != 0)
+ || (v.i[HIGH_HALF] & 0x7fffffff) > 0x7ff00000)
+ return y;
+ if (ABS(y) > 1.0e20) return (y>0)?0:INF.x;
k = checkint(y);
- if (k == 0 || y < 0) return NaNQ.x;
- else return (k==1)?0:x; /* return 0 */
+ if (k == -1)
+ return y < 0 ? 1.0/x : x;
+ else
+ return y < 0 ? 1.0/ABS(x) : 0.0; /* return 0 */
}
/* if x<0 */
if (u.i[HIGH_HALF] < 0) {
k = checkint(y);
- if (k==0) return NaNQ.x; /* y not integer and x<0 */
- return (k==1)?upow(-x,y):-upow(-x,y); /* if y even or odd */
+ if (k==0) {
+ if ((v.i[HIGH_HALF] & 0x7fffffff) == 0x7ff00000 && v.i[LOW_HALF] == 0) {
+ if (x == -1.0) return 1.0;
+ else if (x > -1.0) return v.i[HIGH_HALF] < 0 ? INF.x : 0.0;
+ else return v.i[HIGH_HALF] < 0 ? 0.0 : INF.x;
+ }
+ else if (u.i[HIGH_HALF] == 0xfff00000 && u.i[LOW_HALF] == 0)
+ return y < 0 ? 0.0 : INF.x;
+ return NaNQ.x; /* y not integer and x<0 */
+ }
+ else if (u.i[HIGH_HALF] == 0xfff00000 && u.i[LOW_HALF] == 0)
+ {
+ if (k < 0)
+ return y < 0 ? nZERO.x : nINF.x;
+ else
+ return y < 0 ? 0.0 : INF.x;
+ }
+ return (k==1)?__ieee754_pow(-x,y):-__ieee754_pow(-x,y); /* if y even or odd */
}
/* x>0 */
qx = u.i[HIGH_HALF]&0x7fffffff; /* no sign */
@@ -111,7 +132,8 @@ double __ieee754_pow(double x, double y) {
if (qx > 0x7ff00000 || (qx == 0x7ff00000 && u.i[LOW_HALF] != 0)) return NaNQ.x;
/* if 0<x<2^-0x7fe */
- if (qy > 0x7ff00000 || (qy == 0x7ff00000 && v.i[LOW_HALF] != 0)) return NaNQ.x;
+ if (qy > 0x7ff00000 || (qy == 0x7ff00000 && v.i[LOW_HALF] != 0))
+ return x == 1.0 ? 1.0 : NaNQ.x;
/* if y<2^-0x7fe */
if (qx == 0x7ff00000) /* x= 2^-0x3ff */
@@ -124,7 +146,7 @@ double __ieee754_pow(double x, double y) {
if (y<0) return (x<1.0)?INF.x:0;
}
- if (x == 1.0) return NaNQ.x;
+ if (x == 1.0) return 1.0;
if (y>0) return (x>1.0)?INF.x:0;
if (y<0) return (x<1.0)?INF.x:0;
return 0; /* unreachable, to make the compiler happy */
@@ -148,7 +170,7 @@ static double power1(double x, double y) {
a2 = (a-a1)+aa;
error = error*ABS(y);
t = __exp1(a1,a2,1.9e16*error);
- return (t >= 0)?t:slowpow(x,y,z);
+ return (t >= 0)?t:__slowpow(x,y,z);
}
/****************************************************************************/