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 ctan, ctanh missing underflows (bug 18595) [committed]


Similar to various other bugs in this area, ctan and ctanh can fail to
raise the underflow exception for some cases of results that are tiny
and inexact.  This patch forces the exception in a similar way to
previous fixes.

Tested for x86_64 and x86.  Committed.

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

2015-09-15  Joseph Myers  <joseph@codesourcery.com>

	[BZ #18595]
	* math/s_ctan.c (__ctan): Force underflow exception for results
	whose real or imaginary part has small absolute value.
	* math/s_ctanf.c (__ctanf): Likewise.
	* math/s_ctanh.c (__ctanh): Likewise.
	* math/s_ctanhf.c (__ctanhf): Likewise.
	* math/s_ctanhl.c (__ctanhl): Likewise.
	* math/s_ctanl.c (__ctanl): Likewise.
	* math/auto-libm-test-in: Do not allow missing underflow for ctan
	and ctanh.  Add more tests of ctan and ctanh.

diff --git a/math/auto-libm-test-in b/math/auto-libm-test-in
index 4a8017c..8e236c3 100644
--- a/math/auto-libm-test-in
+++ b/math/auto-libm-test-in
@@ -1245,11 +1245,14 @@ ctan 0x1.921fb6p+0 0x1p-149
 ctan 0x1.921fb54442d18p+0 0x1p-1074
 ctan 0x1.921fb54442d1846ap+0 0x1p-16445
 
-# Bug 18595: underflow exception may be missing
-ctan min 0 missing-underflow
-ctan -min 0 missing-underflow
-ctan min_subnorm 0 missing-underflow
-ctan -min_subnorm 0 missing-underflow
+ctan min 0
+ctan -min 0
+ctan min_subnorm 0
+ctan -min_subnorm 0
+ctan 0 min
+ctan 0 -min
+ctan 0 min_subnorm
+ctan 0 -min_subnorm
 
 ctanh 0 0
 ctanh 0 -0
@@ -1285,11 +1288,14 @@ ctanh 0x1p-149 0x1.921fb6p+0
 ctanh 0x1p-1074 0x1.921fb54442d18p+0
 ctanh 0x1p-16445 0x1.921fb54442d1846ap+0
 
-# Bug 18595: underflow exception may be missing
-ctanh 0 min missing-underflow
-ctanh 0 -min missing-underflow
-ctanh 0 min_subnorm missing-underflow
-ctanh 0 -min_subnorm missing-underflow
+ctanh 0 min
+ctanh 0 -min
+ctanh 0 min_subnorm
+ctanh 0 -min_subnorm
+ctanh min 0
+ctanh -min 0
+ctanh min_subnorm 0
+ctanh -min_subnorm 0
 
 erf 0
 erf -0
diff --git a/math/s_ctan.c b/math/s_ctan.c
index eaf31fa..bcf5cfc 100644
--- a/math/s_ctan.c
+++ b/math/s_ctan.c
@@ -110,6 +110,16 @@ __ctan (__complex__ double x)
 	  __real__ res = sinrx * cosrx / den;
 	  __imag__ res = sinhix * coshix / den;
 	}
+      if (fabs (__real__ res) < DBL_MIN)
+	{
+	  double force_underflow = __real__ res * __real__ res;
+	  math_force_eval (force_underflow);
+	}
+      if (fabs (__imag__ res) < DBL_MIN)
+	{
+	  double force_underflow = __imag__ res * __imag__ res;
+	  math_force_eval (force_underflow);
+	}
     }
 
   return res;
diff --git a/math/s_ctanf.c b/math/s_ctanf.c
index e0a6b8f..683ab6e 100644
--- a/math/s_ctanf.c
+++ b/math/s_ctanf.c
@@ -110,6 +110,16 @@ __ctanf (__complex__ float x)
 	  __real__ res = sinrx * cosrx / den;
 	  __imag__ res = sinhix * coshix / den;
 	}
+      if (fabsf (__real__ res) < FLT_MIN)
+	{
+	  float force_underflow = __real__ res * __real__ res;
+	  math_force_eval (force_underflow);
+	}
+      if (fabsf (__imag__ res) < FLT_MIN)
+	{
+	  float force_underflow = __imag__ res * __imag__ res;
+	  math_force_eval (force_underflow);
+	}
     }
 
   return res;
diff --git a/math/s_ctanh.c b/math/s_ctanh.c
index 1347d07..76a0501 100644
--- a/math/s_ctanh.c
+++ b/math/s_ctanh.c
@@ -110,6 +110,16 @@ __ctanh (__complex__ double x)
 	  __real__ res = sinhrx * coshrx / den;
 	  __imag__ res = sinix * cosix / den;
 	}
+      if (fabs (__real__ res) < DBL_MIN)
+	{
+	  double force_underflow = __real__ res * __real__ res;
+	  math_force_eval (force_underflow);
+	}
+      if (fabs (__imag__ res) < DBL_MIN)
+	{
+	  double force_underflow = __imag__ res * __imag__ res;
+	  math_force_eval (force_underflow);
+	}
     }
 
   return res;
diff --git a/math/s_ctanhf.c b/math/s_ctanhf.c
index 14e1371..9d15c3e 100644
--- a/math/s_ctanhf.c
+++ b/math/s_ctanhf.c
@@ -110,6 +110,16 @@ __ctanhf (__complex__ float x)
 	  __real__ res = sinhrx * coshrx / den;
 	  __imag__ res = sinix * cosix / den;
 	}
+      if (fabsf (__real__ res) < FLT_MIN)
+	{
+	  float force_underflow = __real__ res * __real__ res;
+	  math_force_eval (force_underflow);
+	}
+      if (fabsf (__imag__ res) < FLT_MIN)
+	{
+	  float force_underflow = __imag__ res * __imag__ res;
+	  math_force_eval (force_underflow);
+	}
     }
 
   return res;
diff --git a/math/s_ctanhl.c b/math/s_ctanhl.c
index 6b9dfc5..9c15bb3 100644
--- a/math/s_ctanhl.c
+++ b/math/s_ctanhl.c
@@ -117,6 +117,16 @@ __ctanhl (__complex__ long double x)
 	  __real__ res = sinhrx * coshrx / den;
 	  __imag__ res = sinix * cosix / den;
 	}
+      if (fabsl (__real__ res) < LDBL_MIN)
+	{
+	  long double force_underflow = __real__ res * __real__ res;
+	  math_force_eval (force_underflow);
+	}
+      if (fabsl (__imag__ res) < LDBL_MIN)
+	{
+	  long double force_underflow = __imag__ res * __imag__ res;
+	  math_force_eval (force_underflow);
+	}
     }
 
   return res;
diff --git a/math/s_ctanl.c b/math/s_ctanl.c
index 0fd0039..48ab81b 100644
--- a/math/s_ctanl.c
+++ b/math/s_ctanl.c
@@ -117,6 +117,16 @@ __ctanl (__complex__ long double x)
 	  __real__ res = sinrx * cosrx / den;
 	  __imag__ res = sinhix * coshix / den;
 	}
+      if (fabsl (__real__ res) < LDBL_MIN)
+	{
+	  long double force_underflow = __real__ res * __real__ res;
+	  math_force_eval (force_underflow);
+	}
+      if (fabsl (__imag__ res) < LDBL_MIN)
+	{
+	  long double force_underflow = __imag__ res * __imag__ res;
+	  math_force_eval (force_underflow);
+	}
     }
 
   return res;

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