]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
libm-test.inc: Fix tests where cos(PI/2) != 0.
authorCarlos O'Donell <carlos@redhat.com>
Thu, 11 Apr 2013 12:52:18 +0000 (08:52 -0400)
committerCarlos O'Donell <carlos@redhat.com>
Thu, 11 Apr 2013 12:52:18 +0000 (08:52 -0400)
The value of PI is never exactly PI in any floating point representation,
and the value of PI/2 is never PI/2. It is wrong to expect cos(M_PI_2l)
to return 0, instead it will return an answer that is  non-zero because
M_PI_2l doesn't round to exactly PI/2 in the type used.

That is to say that the correct answer is to do the following:
* Take PI or PI/2.
* Round to the floating point representation.
* Take the rounded value and compute an infinite precision cos or sin.
* Use the rounded result of the infinite precision cos or sin as the
  answer to the test.

I used printf to do the type rounding, and Wolfram's Alpha to do the
infinite precision cos calculations.

The following changes bring x86-64 and x86 to 1/2 ulp for two tests.
It shows that the x86 cos implementation is quite good, and that
our test are flawed.

Unfortunately given that the rounding errors are type dependent we
need to fix this for each type. No regressions on x86-64 or x86.

---

2013-04-11  Carlos O'Donell  <carlos@redhat.com>

* math/libm-test.inc (cos_test): Fix PI/2 test.
(sincos_test): Likewise.
* sysdeps/x86_64/fpu/libm-test-ulps: Regenerate.
* sysdeps/i386/fpu/libm-test-ulps: Regenerate.

ChangeLog
math/libm-test.inc
sysdeps/i386/fpu/libm-test-ulps
sysdeps/x86_64/fpu/libm-test-ulps

index c64d69006cab22174b054efd0e3a99f307f425a3..36efa0b02b8b42f626ae63a40aaee8ac37419ffc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2013-04-11  Carlos O'Donell  <carlos@redhat.com>
+
+       * math/libm-test.inc (cos_test): Fix PI/2 test.
+       (sincos_test): Likewise.
+       * sysdeps/x86_64/fpu/libm-test-ulps: Regenerate.
+       * sysdeps/i386/fpu/libm-test-ulps: Regenerate.
+
 2013-04-11  Andreas Schwab  <schwab@suse.de>
 
        [BZ #13988]
index 78d21074a6925a982f6a7d80f98c2edd9f63e8f8..0049fcda38ab3e12e06213c9f24536dd61173821 100644 (file)
@@ -5330,7 +5330,31 @@ cos_test (void)
 
   TEST_f_f (cos, M_PI_6l * 2.0, 0.5);
   TEST_f_f (cos, M_PI_6l * 4.0, -0.5);
-  TEST_f_f (cos, M_PI_2l, 0);
+
+  /* The value of M_PI_2l is never exactly PI/2, and therefore the
+     answer is never exactly zero. The answer is equal to the error
+     in rounding PI/2 for the type used.  Thus the answer is unique
+     to each type.  */
+#ifdef TEST_FLOAT
+  /* 32-bit float.  */
+  TEST_f_f (cos, M_PI_2l, -4.371139000186241438857289400265215e-8L);
+#endif
+#if defined TEST_DOUBLE || (defined TEST_LDOUBLE && LDBL_MANT_DIG == 53)
+  /* 64-bit double or 64-bit long double.  */
+  TEST_f_f (cos, M_PI_2l, 6.123233995736765886130329661375001e-17L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG == 64
+  /* 96-bit long double.  */
+  TEST_f_f (cos, M_PI_2l, -2.50827880633416601177866354016537e-20L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG == 106
+  /* 128-bit IBM long double.  */
+  TEST_f_f (cos, M_PI_2l, 1.082856673921913968223746169860580e-32L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG == 113
+  /* 128-bit long double.  */
+  TEST_f_f (cos, M_PI_2l, 4.335905065061890512398522013021675e-35L);
+#endif
 
   TEST_f_f (cos, 0.75L, 0.731688868873820886311838753000084544L);
 
@@ -12134,7 +12158,31 @@ sincos_test (void)
   TEST_extra (sincos, minus_infty, qnan_value, qnan_value, INVALID_EXCEPTION);
   TEST_extra (sincos, qnan_value, qnan_value, qnan_value);
 
-  TEST_extra (sincos, M_PI_2l, 1, 0);
+  /* The value of M_PI_2l is never exactly PI/2, and therefore the
+     answer is never exactly zero. The answer is equal to the error
+     in rounding PI/2 for the type used.  Thus the answer is unique
+     to each type.  */
+#ifdef TEST_FLOAT
+  /* 32-bit float.  */
+  TEST_extra (sincos, M_PI_2l, 1, -4.371139000186241438857289400265215e-8L);
+#endif
+#if defined TEST_DOUBLE || (defined TEST_LDOUBLE && LDBL_MANT_DIG == 53)
+  /* 64-bit double or 64-bit long double.  */
+  TEST_extra (sincos, M_PI_2l, 1, 6.123233995736765886130329661375001e-17L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG == 64
+  /* 96-bit long double.  */
+  TEST_extra (sincos, M_PI_2l, 1, -2.50827880633416601177866354016537e-20L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG == 106
+  /* 128-bit IBM long double.  */
+  TEST_extra (sincos, M_PI_2l, 1, 1.082856673921913968223746169860580e-32L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG == 113
+  /* 128-bit long double.  */
+  TEST_extra (sincos, M_PI_2l, 1, 4.335905065061890512398522013021675e-35L);
+#endif
+
   TEST_extra (sincos, M_PI_6l, 0.5, 0.86602540378443864676372317075293616L);
   TEST_extra (sincos, M_PI_6l*2.0, 0.86602540378443864676372317075293616L, 0.5);
   TEST_extra (sincos, 0.75L, 0.681638760023334166733241952779893935L, 0.731688868873820886311838753000084544L);
index 4de455c8c04ee25ecc34c061896f12cae328dec8..fecaa94d45b33cfcc2373db856823e2dbc4cd85f 100644 (file)
@@ -4149,13 +4149,6 @@ idouble: 2
 ifloat: 1
 ildouble: 1
 ldouble: 1
-Test "cos (pi/2) == 0":
-double: 1
-float: 1
-idouble: 1
-ifloat: 1
-ildouble: 1
-ldouble: 1
 
 # cos_downward
 Test "cos_downward (1) == 0.5403023058681397174009366074429766037323":
@@ -5513,13 +5506,6 @@ idouble: 1
 ifloat: 1
 ildouble: 1
 ldouble: 1
-Test "sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res":
-double: 1
-float: 1
-idouble: 1
-ifloat: 1
-ildouble: 1
-ldouble: 1
 
 # sinh
 Test "sinh (0.75) == 0.822316731935829980703661634446913849":
index 28f4bfc0de216602fd51cf0756580a837cf0756a..9c9c47344902218645097f1997b06e3de23fb3e6 100644 (file)
@@ -4717,13 +4717,6 @@ idouble: 2
 ifloat: 1
 ildouble: 1
 ldouble: 1
-Test "cos (pi/2) == 0":
-double: 1
-float: 1
-idouble: 1
-ifloat: 1
-ildouble: 1
-ldouble: 1
 
 # cos_downward
 Test "cos_downward (1) == 0.5403023058681397174009366074429766037323":
@@ -5984,13 +5977,6 @@ idouble: 1
 ifloat: 1
 ildouble: 1
 ldouble: 1
-Test "sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res":
-double: 1
-float: 1
-idouble: 1
-ifloat: 1
-ildouble: 1
-ldouble: 1
 Test "sincos (pi/6, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in cos_res":
 float: 1
 ifloat: 1