This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Fix ldbl-128ibm hypotl inaccuracy for arguments with large ratio(bug 14868)
- From: "Joseph S. Myers" <joseph at codesourcery dot com>
- To: <libc-alpha at sourceware dot org>
- Date: Wed, 21 Nov 2012 23:55:14 +0000
- Subject: Fix ldbl-128ibm hypotl inaccuracy for arguments with large ratio(bug 14868)
Bug 14868 is inaccuracy of ldbl128-ibm hypotl when the ratio of the
arguments is above 2**60, but not big enough for a+b to be a correct
calculation of the result. 2**60 is the ratio used in the dbl-64
code; this patch fixes the ldbl128-ibm code by changing the ratio
there to 2**120.
Tested that this fixes the test in question, and the previously seen
16 ulp failures for csqrtl, on powerpc, and tested x86_64 and x86 that
no new ulps are needed for the new test. (On powerpc there's still a
spurious underflow exception from csqrtl in the results, but that
appears to be a separate bug.)
2012-11-21 Joseph Myers <joseph@codesourcery.com>
[BZ #14868]
* sysdeps/ieee754/ldbl-128ibm/e_hypotl.c (__ieee754_hypotl):
Return a+b for ratio over 2**120, not 2**60.
* math/libm-test.inc (hypot_test): Add another test.
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 2a60557..67cb190 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -5730,6 +5730,8 @@ hypot_test (void)
TEST_ff_f (hypot, 0.75L, 1.25L, 1.45773797371132511771853821938639577L);
+ TEST_ff_f (hypot, 1.0L, 0x1p-61L, 1.0L);
+
#if !(defined TEST_FLOAT && defined TEST_INLINE)
TEST_ff_f (hypot, 0x3p125L, 0x4p125L, 0x5p125L);
TEST_ff_f (hypot, 0x1.234566p-126L, 0x1.234566p-126L, 1.891441686191081936598531534017449451173e-38L);
diff --git a/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c b/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c
index 00bfb15..ce21194 100644
--- a/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c
@@ -61,7 +61,7 @@ __ieee754_hypotl(long double x, long double y)
if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
a = fabsl(a); /* a <- |a| */
b = fabsl(b); /* b <- |b| */
- if((ha-hb)>0x3c0000000000000LL) {return a+b;} /* x/y > 2**60 */
+ if((ha-hb)>0x780000000000000LL) {return a+b;} /* x/y > 2**120 */
k=0;
kld = 1.0L;
if(ha > 0x5f30000000000000LL) { /* a>2**500 */
--
Joseph S. Myers
joseph@codesourcery.com