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 ldbl-96 hypotl of subnormals (bug 15529)


Examining the listed LSB failures showed bug 15529, ldbl-96 hypotl
giving incorrect results for subnormal operands because, when
multiplying by 2^16382, it actually multiplied by an invalid value
with the high bit of the mantissa (that is explicit in the ldbl-96
format) not set.  This patch fixes the code to use a correct
representation of 2^16382.  Tested x86_64 and x86.

2013-05-24  Joseph Myers  <joseph@codesourcery.com>

	[BZ #15529]
	* sysdeps/ieee754/ldbl-96/e_hypotl.c (__ieee754_hypotl): Set high
	bit of mantissa of 2^16382.
	* math/libm-test.inc (hypot_test_data): Add more tests.

diff --git a/math/libm-test.inc b/math/libm-test.inc
index a03647a..ef43475 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -9380,6 +9380,19 @@ static const struct test_ff_f_data hypot_test_data[] =
 #if defined TEST_LDOUBLE && LDBL_MAX_EXP >= 16384 && !defined TEST_INLINE
     TEST_ff_f (hypot, 0x3p16381L, 0x4p16381L, 0x5p16381L),
 #endif
+
+    TEST_ff_f (hypot, 0x1p-149L, 0x1p-149L, 1.9817352931807469938024533350782879785095e-45L, UNDERFLOW_EXCEPTION_FLOAT),
+
+#ifndef TEST_FLOAT
+    TEST_ff_f (hypot, 0x1p-1074L, 0x1p-1074L, 6.9871433705131320800651344656990806305791e-324L, UNDERFLOW_EXCEPTION_DOUBLE),
+#endif
+
+#if defined TEST_LDOUBLE && LDBL_MIN_EXP <= -16381 && !defined TEST_INLINE
+    TEST_ff_f (hypot, 0x1p-16445L, 0x1p-16445L, 5.1550906155442528702558159159596215039925e-4951L, UNDERFLOW_EXCEPTION),
+# if LDBL_MANT_DIG >= 113
+    TEST_ff_f (hypot, 0x1p-16494L, 0x1p-16494L, 9.1572804726500807075521065242888978445857e-4966L, UNDERFLOW_EXCEPTION),
+# endif
+#endif
   };
 
 static void
diff --git a/sysdeps/ieee754/ldbl-96/e_hypotl.c b/sysdeps/ieee754/ldbl-96/e_hypotl.c
index 306f929..7895488 100644
--- a/sysdeps/ieee754/ldbl-96/e_hypotl.c
+++ b/sysdeps/ieee754/ldbl-96/e_hypotl.c
@@ -85,7 +85,7 @@ long double __ieee754_hypotl(long double x, long double y)
 		u_int32_t high,low;
 		GET_LDOUBLE_WORDS(exp,high,low,b);
 		if((high|low)==0) return a;
-		SET_LDOUBLE_WORDS(t1, 0x7ffd, 0, 0);	/* t1=2^16382 */
+		SET_LDOUBLE_WORDS(t1, 0x7ffd, 0x80000000, 0); /* t1=2^16382 */
 		b *= t1;
 		a *= t1;
 		k -= 16382;

-- 
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]