diff options
author | Carlos O'Donell <carlos@redhat.com> | 2013-04-11 08:52:18 -0400 |
---|---|---|
committer | Carlos O'Donell <carlos@redhat.com> | 2013-04-11 08:52:18 -0400 |
commit | aba5e333d4bde2710d9e91dfbc660bd881aef1f7 (patch) | |
tree | c2bdb3555b7befa68c110058bee97ef18610369c /math | |
parent | 4f682b2ae941b9bacde6015799b7ae77301a6d87 (diff) | |
download | glibc-aba5e333d4bde2710d9e91dfbc660bd881aef1f7.tar.gz glibc-aba5e333d4bde2710d9e91dfbc660bd881aef1f7.tar.xz glibc-aba5e333d4bde2710d9e91dfbc660bd881aef1f7.zip |
libm-test.inc: Fix tests where cos(PI/2) != 0.
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.
Diffstat (limited to 'math')
-rw-r--r-- | math/libm-test.inc | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/math/libm-test.inc b/math/libm-test.inc index 78d21074a6..0049fcda38 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -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); |