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


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