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 hypotf overflow/underflow (bug 13840)


This patch fixes overflow and underflow problems in
sysdeps/ieee754/flt-32/e_hypotf.c.  This scales by 2**60 in an attempt
to avoid the internal x**x+y**y overflowing.  But as FLT_MAX is just
under 2**128, scaling down by 2**60 isn't enough for large inputs.
And while there is a separate case for subnormal inputs, for small
normal inputs the scaling up by 2**60 still leaves x**x+y**y subnormal
(so with loss of precision).

Tested x86_64 and x86 (no ulps updates required).  The TEST_INLINE
conditionals are based on failures observed with the x86 inline
implementation (it's possible that the test without such a conditional
will need one as well depending on the exact compiler version /
configuration in use, I just didn't find it to be needed in my
testing).

2012-03-13  Joseph Myers  <joseph@codesourcery.com>

	[BZ #13840]
	* sysdeps/ieee754/flt-32/e_hypotf.c (__ieee754_hypotf): Scale by
	2**70, not 2**60.
	* math/libm-test.inc (hypot_test): Add more tests.

diff --git a/math/libm-test.inc b/math/libm-test.inc
index 39cda66..191f359 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -3557,6 +3557,19 @@ hypot_test (void)
 
   TEST_ff_f (hypot, 0.75L, 1.25L, 1.45773797371132511771853821938639577L);
 
+#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);
+#endif
+
+#ifndef TEST_FLOAT
+  TEST_ff_f (hypot, 0x3p1021L, 0x4p1021L, 0x5p1021L);
+#endif
+
+#if defined TEST_LDOUBLE && LDBL_MAX_EXP >= 16384 && !defined TEST_INLINE
+  TEST_ff_f (hypot, 0x3p16381L, 0x4p16381L, 0x5p16381L);
+#endif
+
   END (hypot);
 }
 
diff --git a/sysdeps/ieee754/flt-32/e_hypotf.c b/sysdeps/ieee754/flt-32/e_hypotf.c
index 97e7d34..69dae12 100644
--- a/sysdeps/ieee754/flt-32/e_hypotf.c
+++ b/sysdeps/ieee754/flt-32/e_hypotf.c
@@ -38,8 +38,8 @@ __ieee754_hypotf(float x, float y)
 	       if(hb == 0x7f800000) w = b;
 	       return w;
 	   }
-	   /* scale a and b by 2**-60 */
-	   ha -= 0x1e000000; hb -= 0x1e000000;	k += 60;
+	   /* scale a and b by 2**-70 */
+	   ha -= 0x23000000; hb -= 0x23000000;	k += 70;
 	   SET_FLOAT_WORD(a,ha);
 	   SET_FLOAT_WORD(b,hb);
 	}
@@ -50,10 +50,10 @@ __ieee754_hypotf(float x, float y)
 		b *= t1;
 		a *= t1;
 		k -= 126;
-	    } else {		/* scale a and b by 2^60 */
-		ha += 0x1e000000;	/* a *= 2^60 */
-		hb += 0x1e000000;	/* b *= 2^60 */
-		k -= 60;
+	    } else {		/* scale a and b by 2^70 */
+		ha += 0x23000000;	/* a *= 2^70 */
+		hb += 0x23000000;	/* b *= 2^70 */
+		k -= 70;
 		SET_FLOAT_WORD(a,ha);
 		SET_FLOAT_WORD(b,hb);
 	    }

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