From: Joseph Myers Date: Mon, 13 Jun 2016 21:43:22 +0000 (+0000) Subject: Fix dbl-64 atan2 (sNaN, qNaN) (bug 20252). X-Git-Tag: glibc-2.24~106 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a2ae1696f7c6cf269b3a734bce4d9d3620745854;p=thirdparty%2Fglibc.git Fix dbl-64 atan2 (sNaN, qNaN) (bug 20252). 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. [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/ChangeLog b/ChangeLog index d6b12ff9175..1d2c3e3d864 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2016-06-13 Joseph Myers + [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. + * math/libm-test.inc (cimag_test_data): Add sNaN tests. (conj_test_data): Likewise. (copysign_test_data): Likewise. diff --git a/math/libm-test.inc b/math/libm-test.inc index a8414ec9ca6..010743f98c6 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 22e8fb8fef5..0838907019f 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];