This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Fix ldbl-96 hypotl of subnormals (bug 15529)
- From: "Joseph S. Myers" <joseph at codesourcery dot com>
- To: <libc-alpha at sourceware dot org>
- Date: Fri, 24 May 2013 20:27:12 +0000
- Subject: 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