Fix cacos (+Inf + finite*i) in round-downward mode (bug 16928).
authorJoseph Myers <joseph@codesourcery.com>
Wed, 14 May 2014 12:37:24 +0000 (12:37 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Wed, 14 May 2014 12:37:24 +0000 (12:37 +0000)
According to C99/C11 Annex G, cacos applied to a value with real part
+Inf and finite imaginary part should produce a result with real part
+0.  glibc wrongly produces a result with real part -0 in FE_DOWNWARD
mode.  This patch fixes this by checking for zero results in the
relevant case of non-finite arguments (where there should never be a
result with -0 real part), and converts the tests of cacos to
ALL_RM_TEST.

Tested x86_64 and x86 and ulps updated accordingly.

[BZ #16928]
* math/s_cacos.c (__cacos): Ensure zero real part of result from
non-finite arguments is +0.
* math/s_cacosf.c (__cacosf): Likewise.
* math/s_cacosl.c (__cacosl): Likewise.
* math/libm-test.inc (cacos_test): Use ALL_RM_TEST.
* sysdeps/i386/fpu/libm-test-ulps: Update.
* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.

ChangeLog
NEWS
math/libm-test.inc
math/s_cacos.c
math/s_cacosf.c
math/s_cacosl.c
sysdeps/i386/fpu/libm-test-ulps
sysdeps/x86_64/fpu/libm-test-ulps

index a4376290adfa902b8229a43acb2471e297e248f3..37ca8c03be5efcc2bda922f106b3aab36ff1f694 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2014-05-14  Joseph Myers  <joseph@codesourcery.com>
 
+       [BZ #16928]
+       * math/s_cacos.c (__cacos): Ensure zero real part of result from
+       non-finite arguments is +0.
+       * math/s_cacosf.c (__cacosf): Likewise.
+       * math/s_cacosl.c (__cacosl): Likewise.
+       * math/libm-test.inc (cacos_test): Use ALL_RM_TEST.
+       * sysdeps/i386/fpu/libm-test-ulps: Update.
+       * sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
+
        [BZ #16927]
        * sysdeps/i386/fpu/e_acosh.S (__ieee754_acosh): Use fabs on x-1
        value.
diff --git a/NEWS b/NEWS
index 974d2c80a9325ad9b8ea74b3026990eb81d6549d..de9e8a280e78375c23d4b9f36d6b5c394abcae1a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -17,7 +17,7 @@ Version 2.20
   16713, 16714, 16731, 16739, 16740, 16743, 16754, 16758, 16759, 16760,
   16770, 16786, 16789, 16791, 16799, 16800, 16815, 16823, 16824, 16831,
   16838, 16854, 16876, 16877, 16885, 16888, 16890, 16912, 16916, 16922,
-  16927, 16932.
+  16927, 16928, 16932.
 
 * The minimum Linux kernel version that this version of the GNU C Library
   can be used with is 2.6.32.
index b4177e8f8e0288f3e86e7790abaabb97784e928f..de7bc8ad9404b723fc2399d626b32a2468c63fb2 100644 (file)
@@ -2615,9 +2615,7 @@ static const struct test_c_c_data cacos_test_data[] =
 static void
 cacos_test (void)
 {
-  START (cacos, 0);
-  RUN_TEST_LOOP_c_c (cacos, cacos_test_data, );
-  END_COMPLEX;
+  ALL_RM_TEST (cacos, 0, cacos_test_data, RUN_TEST_LOOP_c_c, END_COMPLEX);
 }
 
 static const struct test_c_c_data cacosh_test_data[] =
index d0aaba4e6ac0c406ff2353033f38357d3aba2e6e..2c22817d4d076786c74bf5ce163bc916ef6801e9 100644 (file)
@@ -34,6 +34,8 @@ __cacos (__complex__ double x)
       y = __casin (x);
 
       __real__ res = (double) M_PI_2 - __real__ y;
+      if (__real__ res == 0.0)
+       __real__ res = 0.0;
       __imag__ res = -__imag__ y;
     }
   else
index 9eaeeec53dc755d11168b69cdb403f099746eee8..1c9d8b9186e10ce1a9c51b27f705246102bdeaff 100644 (file)
@@ -34,6 +34,8 @@ __cacosf (__complex__ float x)
       y = __casinf (x);
 
       __real__ res = (float) M_PI_2 - __real__ y;
+      if (__real__ res == 0.0f)
+       __real__ res = 0.0f;
       __imag__ res = -__imag__ y;
     }
   else
index b9d34930d656fdbbef5d6312bb2cd0643aed70dd..8688d3cd36fc942a49b7205ea17b6ba046f4ef83 100644 (file)
@@ -34,6 +34,8 @@ __cacosl (__complex__ long double x)
       y = __casinl (x);
 
       __real__ res = M_PI_2l - __real__ y;
+      if (__real__ res == 0.0L)
+       __real__ res = 0.0L;
       __imag__ res = -__imag__ y;
     }
   else
index ccef44ac638786739e8dbca6eb88a974170bfcaa..946cad489b52d5706771200e194f8100c25706e3 100644 (file)
@@ -173,6 +173,54 @@ ifloat: 1
 ildouble: 2
 ldouble: 2
 
+Function: Real part of "cacos_downward":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "cacos_downward":
+double: 3
+float: 3
+idouble: 3
+ifloat: 3
+ildouble: 5
+ldouble: 5
+
+Function: Real part of "cacos_towardzero":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "cacos_towardzero":
+double: 3
+float: 3
+idouble: 3
+ifloat: 3
+ildouble: 5
+ldouble: 5
+
+Function: Real part of "cacos_upward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "cacos_upward":
+double: 4
+float: 4
+idouble: 4
+ifloat: 4
+ildouble: 5
+ldouble: 5
+
 Function: Real part of "cacosh":
 double: 1
 float: 1
index ad8ae9ce5c6d9100664154ac976ebddfb754ceb0..d47287696c6e2bdabe4bc296d8f20500c6e13f9b 100644 (file)
@@ -199,6 +199,54 @@ ifloat: 2
 ildouble: 2
 ldouble: 2
 
+Function: Real part of "cacos_downward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "cacos_downward":
+double: 5
+float: 3
+idouble: 5
+ifloat: 3
+ildouble: 5
+ldouble: 5
+
+Function: Real part of "cacos_towardzero":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "cacos_towardzero":
+double: 5
+float: 3
+idouble: 5
+ifloat: 3
+ildouble: 5
+ldouble: 5
+
+Function: Real part of "cacos_upward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "cacos_upward":
+double: 4
+float: 4
+idouble: 4
+ifloat: 4
+ildouble: 5
+ldouble: 5
+
 Function: Real part of "cacosh":
 double: 1
 float: 2