diff options
Diffstat (limited to 'sysdeps/ieee754')
-rw-r--r-- | sysdeps/ieee754/dbl-64/e_pow.c | 4 | ||||
-rw-r--r-- | sysdeps/ieee754/flt-32/e_powf.c | 4 |
2 files changed, 8 insertions, 0 deletions
diff --git a/sysdeps/ieee754/dbl-64/e_pow.c b/sysdeps/ieee754/dbl-64/e_pow.c index 3fd5e6507f..513171891c 100644 --- a/sysdeps/ieee754/dbl-64/e_pow.c +++ b/sysdeps/ieee754/dbl-64/e_pow.c @@ -90,6 +90,10 @@ __ieee754_pow(double x, double y) { SET_RESTORE_ROUND (FE_TONEAREST); + /* Avoid internal underflow for tiny y. The exact value of y does + not matter if |y| <= 2**-64. */ + if (ABS (y) < 0x1p-64) + y = y < 0 ? -0x1p-64 : 0x1p-64; z = log1(x,&aa,&error); /* x^y =e^(y log (X)) */ t = y*134217729.0; y1 = t - (t-y); diff --git a/sysdeps/ieee754/flt-32/e_powf.c b/sysdeps/ieee754/flt-32/e_powf.c index 43069479a5..12c408f93c 100644 --- a/sysdeps/ieee754/flt-32/e_powf.c +++ b/sysdeps/ieee754/flt-32/e_powf.c @@ -141,6 +141,10 @@ __ieee754_powf(float x, float y) t2 = v-(t1-u); } else { float s2,s_h,s_l,t_h,t_l; + /* Avoid internal underflow for tiny y. The exact value + of y does not matter if |y| <= 2**-32. */ + if (iy < 0x2f800000) + SET_FLOAT_WORD (y, (hy & 0x80000000) | 0x2f800000); n = 0; /* take care subnormal number */ if(ix<0x00800000) |