summaryrefslogtreecommitdiff
path: root/libc/sysdeps/ieee754
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps/ieee754')
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_pow.c4
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_powf.c4
2 files changed, 8 insertions, 0 deletions
diff --git a/libc/sysdeps/ieee754/dbl-64/e_pow.c b/libc/sysdeps/ieee754/dbl-64/e_pow.c
index 3fd5e6507..513171891 100644
--- a/libc/sysdeps/ieee754/dbl-64/e_pow.c
+++ b/libc/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/libc/sysdeps/ieee754/flt-32/e_powf.c b/libc/sysdeps/ieee754/flt-32/e_powf.c
index 43069479a..12c408f93 100644
--- a/libc/sysdeps/ieee754/flt-32/e_powf.c
+++ b/libc/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)