diff options
author | David S. Miller <davem@davemloft.net> | 2012-11-19 15:26:52 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-11-19 15:31:24 -0800 |
commit | 6d33cc9d9bde501e0906c42ee396d42cb4ca603c (patch) | |
tree | fa106d1ac0b43e69180ba0e497321d56210d4a92 | |
parent | 877f2d8e8def5a278e4b9f4e4dc378f7f8a653b8 (diff) | |
download | glibc-6d33cc9d9bde501e0906c42ee396d42cb4ca603c.tar.gz glibc-6d33cc9d9bde501e0906c42ee396d42cb4ca603c.tar.xz glibc-6d33cc9d9bde501e0906c42ee396d42cb4ca603c.zip |
Fix spurious underflows in ldbl-128 atan implementation.
With help from Joseph Myers. * sysdeps/ieee754/ldbl-128/s_atanl.c (__atanl): Handle tiny and very large arguments properly. * math/libm-test.inc (atan_test): New tests. (atan2_test): New tests. * sysdeps/sparc/fpu/libm-test-ulps: Update. * sysdeps/x86_64/fpu/libm-test-ulps: Update.
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | math/libm-test.inc | 5 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128/s_atanl.c | 17 | ||||
-rw-r--r-- | sysdeps/sparc/fpu/libm-test-ulps | 3 | ||||
-rw-r--r-- | sysdeps/x86_64/fpu/libm-test-ulps | 3 |
5 files changed, 38 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog index f2e166b2e2..7e85f77016 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2012-11-19 David S. Miller <davem@davemloft.net> + + With help from Joseph Myers. + * sysdeps/ieee754/ldbl-128/s_atanl.c (__atanl): Handle tiny and + very large arguments properly. + * math/libm-test.inc (atan_test): New tests. + (atan2_test): New tests. + * sysdeps/sparc/fpu/libm-test-ulps: Update. + * sysdeps/x86_64/fpu/libm-test-ulps: Update. + 2012-11-19 Joseph Myers <joseph@codesourcery.com> [BZ #14856] diff --git a/math/libm-test.inc b/math/libm-test.inc index 0b254e1738..2a60557fd9 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -1187,6 +1187,8 @@ atan_test (void) TEST_f_f (atan, plus_infty, M_PI_2l); TEST_f_f (atan, minus_infty, -M_PI_2l); TEST_f_f (atan, nan_value, nan_value); + TEST_f_f (atan, max_value, M_PI_2l); + TEST_f_f (atan, -max_value, -M_PI_2l); TEST_f_f (atan, 1, M_PI_4l); TEST_f_f (atan, -1, -M_PI_4l); @@ -1295,6 +1297,9 @@ atan2_test (void) TEST_ff_f (atan2, max_value, max_value, M_PI_4l); + TEST_ff_f (atan2, max_value, min_value, M_PI_2l); + TEST_ff_f (atan2, -max_value, -min_value, -M_PI_2l); + TEST_ff_f (atan2, 0.75L, 1, 0.643501108793284386802809228717322638L); TEST_ff_f (atan2, -0.75L, 1.0L, -0.643501108793284386802809228717322638L); TEST_ff_f (atan2, 0.75L, -1.0L, 2.49809154479650885165983415456218025L); diff --git a/sysdeps/ieee754/ldbl-128/s_atanl.c b/sysdeps/ieee754/ldbl-128/s_atanl.c index 0138e792aa..adac0a79e7 100644 --- a/sysdeps/ieee754/ldbl-128/s_atanl.c +++ b/sysdeps/ieee754/ldbl-128/s_atanl.c @@ -167,6 +167,7 @@ static const long double q4 = 2.173623741810414221251136181221172551416E1L; /* q5 = 1.000000000000000000000000000000000000000E0 */ +static const long double huge = 1.0e4930L; long double __atanl (long double x) @@ -197,6 +198,22 @@ __atanl (long double x) return atantbl[83]; } + if (k <= 0x3fc50000) /* |x| < 2**-58 */ + { + /* Raise inexact. */ + if (huge + x > 0.0) + return x; + } + + if (k >= 0x40720000) /* |x| > 2**115 */ + { + /* Saturate result to {-,+}pi/2 */ + if (sign) + return -atantbl[83]; + else + return atantbl[83]; + } + if (sign) x = -x; diff --git a/sysdeps/sparc/fpu/libm-test-ulps b/sysdeps/sparc/fpu/libm-test-ulps index ec0ad66204..432e01181a 100644 --- a/sysdeps/sparc/fpu/libm-test-ulps +++ b/sysdeps/sparc/fpu/libm-test-ulps @@ -102,6 +102,9 @@ float: 1 ifloat: 1 ildouble: 1 ldouble: 1 +Test "atan2 (-max_value, -min_value) == -pi/2": +float: 1 +ifloat: 1 Test "atan2 (0.75, -1.0) == 2.49809154479650885165983415456218025": float: 1 ifloat: 1 diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps index 4767be94db..f33dfed3df 100644 --- a/sysdeps/x86_64/fpu/libm-test-ulps +++ b/sysdeps/x86_64/fpu/libm-test-ulps @@ -162,6 +162,9 @@ ldouble: 1 Test "atan2 (-0.75, -1.0) == -2.49809154479650885165983415456218025": float: 1 ifloat: 1 +Test "atan2 (-max_value, -min_value) == -pi/2": +float: 1 +ifloat: 1 Test "atan2 (0.75, -1.0) == 2.49809154479650885165983415456218025": float: 1 ifloat: 1 |