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 csqrt spurious underflows (bug 18823) [committed]


The csqrt functions scale up small arguments to avoid underflows when
calling hypot functions.  However, even when hypot does not underflow,
a subsequent calculation of 0.5 * hypot can underflow.  This patch
duly increases the threshold and scale factor to avoid such underflows
as well.

Tested for x86_64, x86 and mips64.  Committed.

(auto-libm-test-out diffs omitted below.)

2015-08-17  Joseph Myers  <joseph@codesourcery.com>

	[BZ #18823]
	* math/s_csqrt.c (__csqrt): Increase threshold and scale factor
	for scaling up small arguments.
	* math/s_csqrtf.c (__csqrtf): Likewise.
	* math/s_csqrtl.c (__csqrtl): Likewise.
	* math/auto-libm-test-in: Add more tests of csqrt.
	* math/auto-libm-test-out: Regenerated.

diff --git a/math/auto-libm-test-in b/math/auto-libm-test-in
index 4480371..015041a 100644
--- a/math/auto-libm-test-in
+++ b/math/auto-libm-test-in
@@ -1162,6 +1162,15 @@ csqrt -0x0.ffp1024 0x1.1p-509
 csqrt 0x0.ffp16384 0x1.1p-8189
 csqrt -0x0.ffp16384 0x1.1p-8189
 
+csqrt 0x1p-149 0x1.000002p-126
+csqrt 0x1p-149 0x1.000004p-126
+csqrt 0x1p-1074 0x1.0000000000001p-1022
+csqrt 0x1p-1074 0x1.0000000000002p-1022
+csqrt 0x1p-16445 0x1.0000000000000002p-16382
+csqrt 0x1p-16445 0x1.0000000000000004p-16382
+csqrt 0x1p-16494 0x1.0000000000000000000000000001p-16382
+csqrt 0x1p-16494 0x1.0000000000000000000000000002p-16382
+
 ctan 0 0
 ctan 0 -0
 ctan -0 0
diff --git a/math/s_csqrt.c b/math/s_csqrt.c
index 75da2e7..068534c 100644
--- a/math/s_csqrt.c
+++ b/math/s_csqrt.c
@@ -104,10 +104,10 @@ __csqrt (__complex__ double x)
 		__real__ x = 0.0;
 	      __imag__ x = __scalbn (__imag__ x, -2 * scale);
 	    }
-	  else if (fabs (__real__ x) < DBL_MIN
-		   && fabs (__imag__ x) < DBL_MIN)
+	  else if (fabs (__real__ x) < 2.0 * DBL_MIN
+		   && fabs (__imag__ x) < 2.0 * DBL_MIN)
 	    {
-	      scale = -(DBL_MANT_DIG / 2);
+	      scale = -((DBL_MANT_DIG + 1) / 2);
 	      __real__ x = __scalbn (__real__ x, -2 * scale);
 	      __imag__ x = __scalbn (__imag__ x, -2 * scale);
 	    }
diff --git a/math/s_csqrtf.c b/math/s_csqrtf.c
index 7f45cc1..f7dc3b1 100644
--- a/math/s_csqrtf.c
+++ b/math/s_csqrtf.c
@@ -104,10 +104,10 @@ __csqrtf (__complex__ float x)
 		__real__ x = 0.0f;
 	      __imag__ x = __scalbnf (__imag__ x, -2 * scale);
 	    }
-	  else if (fabsf (__real__ x) < FLT_MIN
-		   && fabsf (__imag__ x) < FLT_MIN)
+	  else if (fabsf (__real__ x) < 2.0f * FLT_MIN
+		   && fabsf (__imag__ x) < 2.0f * FLT_MIN)
 	    {
-	      scale = -(FLT_MANT_DIG / 2);
+	      scale = -((FLT_MANT_DIG + 1) / 2);
 	      __real__ x = __scalbnf (__real__ x, -2 * scale);
 	      __imag__ x = __scalbnf (__imag__ x, -2 * scale);
 	    }
diff --git a/math/s_csqrtl.c b/math/s_csqrtl.c
index 10988ba..a0252e6 100644
--- a/math/s_csqrtl.c
+++ b/math/s_csqrtl.c
@@ -104,10 +104,10 @@ __csqrtl (__complex__ long double x)
 		__real__ x = 0.0L;
 	      __imag__ x = __scalbnl (__imag__ x, -2 * scale);
 	    }
-	  else if (fabsl (__real__ x) < LDBL_MIN
-		   && fabsl (__imag__ x) < LDBL_MIN)
+	  else if (fabsl (__real__ x) < 2.0L * LDBL_MIN
+		   && fabsl (__imag__ x) < 2.0L * LDBL_MIN)
 	    {
-	      scale = -(LDBL_MANT_DIG / 2);
+	      scale = -((LDBL_MANT_DIG + 1) / 2);
 	      __real__ x = __scalbnl (__real__ x, -2 * scale);
 	      __imag__ x = __scalbnl (__imag__ x, -2 * scale);
 	    }

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