Fix dbl-64 atan2 (sNaN, qNaN) (bug 20252) [committed]
Joseph Myers
joseph@codesourcery.com
Mon Jun 13 21:44:00 GMT 2016
The dbl-64 implementation of atan2, passed arguments (sNaN, qNaN),
fails to raise the "invalid" exception. This patch fixes it to add
both arguments, rather than just adding the second argument to itself,
in the case where the second argument is a NaN (which is checked for
before checking for the first argument being a NaN). sNaN tests for
atan2 are added, along with some qNaN tests I noticed were missing but
should have been there by analogy with other tests present.
Tested for x86_64 and x86. Committed.
2016-06-13 Joseph Myers <joseph@codesourcery.com>
[BZ #20252]
* sysdeps/ieee754/dbl-64/e_atan2.c (__ieee754_atan2): Add both
arguments when second argument is a NaN.
* math/libm-test.inc (atan2_test_data): Add sNaN tests and more
qNaN tests.
diff --git a/math/libm-test.inc b/math/libm-test.inc
index a8414ec..010743f 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -1986,6 +1986,18 @@ static const struct test_ff_f_data atan2_test_data[] =
TEST_ff_f (atan2, qnan_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (atan2, -qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (atan2, -qnan_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (atan2, snan_value, qnan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, snan_value, -qnan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -snan_value, qnan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -snan_value, -qnan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, qnan_value, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, qnan_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -qnan_value, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -qnan_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, snan_value, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, snan_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -snan_value, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -snan_value, -snan_value, qnan_value, INVALID_EXCEPTION),
TEST_ff_f (atan2, qnan_value, plus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (atan2, qnan_value, minus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (atan2, qnan_value, plus_zero, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
@@ -2010,6 +2022,30 @@ static const struct test_ff_f_data atan2_test_data[] =
TEST_ff_f (atan2, -qnan_value, -min_subnorm_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (atan2, -qnan_value, max_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (atan2, -qnan_value, -max_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (atan2, snan_value, plus_infty, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, snan_value, minus_infty, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, snan_value, plus_zero, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, snan_value, minus_zero, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, snan_value, 1, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, snan_value, -1, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, snan_value, min_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, snan_value, -min_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, snan_value, min_subnorm_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, snan_value, -min_subnorm_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, snan_value, max_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, snan_value, -max_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -snan_value, plus_infty, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -snan_value, minus_infty, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -snan_value, plus_zero, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -snan_value, minus_zero, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -snan_value, 1, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -snan_value, -1, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -snan_value, min_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -snan_value, -min_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -snan_value, min_subnorm_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -snan_value, -min_subnorm_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -snan_value, max_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -snan_value, -max_value, qnan_value, INVALID_EXCEPTION),
TEST_ff_f (atan2, plus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (atan2, minus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (atan2, plus_zero, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
@@ -2022,6 +2058,8 @@ static const struct test_ff_f_data atan2_test_data[] =
TEST_ff_f (atan2, -min_subnorm_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (atan2, max_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (atan2, -max_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (atan2, plus_infty, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (atan2, minus_infty, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (atan2, plus_zero, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (atan2, minus_zero, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (atan2, 1, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
@@ -2032,6 +2070,30 @@ static const struct test_ff_f_data atan2_test_data[] =
TEST_ff_f (atan2, -min_subnorm_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (atan2, max_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (atan2, -max_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (atan2, plus_infty, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, minus_infty, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, plus_zero, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, minus_zero, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, 1, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -1, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, min_value, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -min_value, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, min_subnorm_value, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -min_subnorm_value, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, max_value, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -max_value, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, plus_infty, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, minus_infty, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, plus_zero, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, minus_zero, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, 1, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -1, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, min_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -min_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, min_subnorm_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -min_subnorm_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, max_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (atan2, -max_value, -snan_value, qnan_value, INVALID_EXCEPTION),
AUTO_TESTS_ff_f (atan2),
};
diff --git a/sysdeps/ieee754/dbl-64/e_atan2.c b/sysdeps/ieee754/dbl-64/e_atan2.c
index 22e8fb8..0838907 100644
--- a/sysdeps/ieee754/dbl-64/e_atan2.c
+++ b/sysdeps/ieee754/dbl-64/e_atan2.c
@@ -91,7 +91,7 @@ __ieee754_atan2 (double y, double x)
if ((ux & 0x7ff00000) == 0x7ff00000)
{
if (((ux & 0x000fffff) | dx) != 0x00000000)
- return x + x;
+ return x + y;
}
num.d = y;
uy = num.i[HIGH_HALF];
--
Joseph S. Myers
joseph@codesourcery.com
More information about the Libc-alpha
mailing list