This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Fix fmod for subnormals (bug 14048)
- From: "Joseph S. Myers" <joseph at codesourcery dot com>
- To: libc-alpha at sourceware dot org
- Cc: Carlos O'Donell <carlos at systemhalted dot org>
- Date: Mon, 28 May 2012 23:53:43 +0000 (UTC)
- Subject: Fix fmod for subnormals (bug 14048)
Bug 14048 is fmod returning incorrect results for some subnormal
inputs - for glibc 2.15 but not 2.11. This is a problem with the
dbl-64/wordsize-64 code (which is new in 2.15): an internal variable
used to store the mantissa while working out the exponent of a
subnormal value was int32_t but needed to be 64-bit.
I propose this patch to fix this. Tested x86_64. Carlos, I'll be
proposing this for 2.15 branch as well.
(I'd think all these fmod/fmodf/fmodl implementations would be better
using __builtin_clz / __builtin_clzll to find the exponents of
subnormals, but such an optimization is a separate issue and probably
shouldn't be backported to 2.15.)
2012-05-28 Joseph Myers <joseph@codesourcery.com>
[BZ #14048]
* sysdeps/ieee754/dbl-64/wordsize-64/e_fmod.c (__ieee754_fmod):
Use int64_t for variable i.
* math/libm-test.inc (fmod_test): Add more tests.
diff --git a/math/libm-test.inc b/math/libm-test.inc
index bb19dee..2b2ca32 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -4123,6 +4123,14 @@ fmod_test (void)
TEST_ff_f (fmod, 6.5, -2.25L, 2.0L);
TEST_ff_f (fmod, -6.5, -2.25L, -2.0L);
+ TEST_ff_f (fmod, 0x0.fffffep-126L, 0x1p-149L, plus_zero);
+#ifndef TEST_FLOAT
+ TEST_ff_f (fmod, 0x0.fffffffffffffp-1022L, 0x1p-1074L, plus_zero);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MIN_EXP <= -16381
+ TEST_ff_f (fmod, 0x0.fffffffffffffffep-16382L, 0x1p-16445L, plus_zero);
+#endif
+
END (fmod);
}
diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/e_fmod.c b/sysdeps/ieee754/dbl-64/wordsize-64/e_fmod.c
index 6d25404..a630d10 100644
--- a/sysdeps/ieee754/dbl-64/wordsize-64/e_fmod.c
+++ b/sysdeps/ieee754/dbl-64/wordsize-64/e_fmod.c
@@ -24,8 +24,8 @@ static const double one = 1.0, Zero[] = {0.0, -0.0,};
double
__ieee754_fmod (double x, double y)
{
- int32_t n,i,ix,iy;
- int64_t hx,hy,hz,sx;
+ int32_t n,ix,iy;
+ int64_t hx,hy,hz,sx,i;
EXTRACT_WORDS64(hx,x);
EXTRACT_WORDS64(hy,y);
--
Joseph S. Myers
joseph@codesourcery.com