about summary refs log tree commit diff
path: root/math/s_csqrtf.c
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2015-08-19 22:42:01 +0000
committerJoseph Myers <joseph@codesourcery.com>2015-08-19 22:42:01 +0000
commit948e12a238715b2931cc42486db9e502ff943e54 (patch)
treec0790fb5b46d6a49e015f15cbec9c45464dd1dc2 /math/s_csqrtf.c
parentb75d1cfce647df871700a9027cde35484127d727 (diff)
downloadglibc-948e12a238715b2931cc42486db9e502ff943e54.tar.gz
glibc-948e12a238715b2931cc42486db9e502ff943e54.tar.xz
glibc-948e12a238715b2931cc42486db9e502ff943e54.zip
Fix csqrt missing underflows (bug 18370).
The csqrt implementations in glibc can miss underflow exceptions when
the real or imaginary part of the result becomes tiny in the course of
scaling down (in particular, multiplication by 0.5) and that scaling
is exact although the relevant part of the mathematical result isn't.
This patch forces the exception in a similar way to previous fixes.

Tested for x86_64 and x86.

	[BZ #18370]
	* math/s_csqrt.c (__csqrt): Force underflow exception for results
	whose real or imaginary part has small absolute value.
	* 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.
	* sysdeps/i386/fpu/libm-test-ulps: Update.
Diffstat (limited to 'math/s_csqrtf.c')
-rw-r--r--math/s_csqrtf.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/math/s_csqrtf.c b/math/s_csqrtf.c
index f7dc3b1cd1..e433f476c2 100644
--- a/math/s_csqrtf.c
+++ b/math/s_csqrtf.c
@@ -148,6 +148,17 @@ __csqrtf (__complex__ float x)
 	      s = __scalbnf (s, scale);
 	    }
 
+	  if (fabsf (r) < FLT_MIN)
+	    {
+	      float force_underflow = r * r;
+	      math_force_eval (force_underflow);
+	    }
+	  if (fabsf (s) < FLT_MIN)
+	    {
+	      float force_underflow = s * s;
+	      math_force_eval (force_underflow);
+	    }
+
 	  __real__ res = r;
 	  __imag__ res = __copysignf (s, __imag__ x);
 	}