This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]