diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | math/libm-test.inc | 69 | ||||
-rw-r--r-- | sysdeps/ieee754/dbl-64/e_remainder.c | 2 |
4 files changed, 79 insertions, 1 deletions
@@ -1,5 +1,11 @@ 2015-11-02 Joseph Myers <joseph@codesourcery.com> + [BZ #19201] + * sysdeps/ieee754/dbl-64/e_remainder.c (__ieee754_remainder): + Check for zero remainder in case of large exponents and ensure + correct sign of result in that case. + * math/libm-test.inc (remainder_test_data): Add more tests. + [BZ #6799] * math/s_nextafter.c: Include <errno.h>. (__nextafter): Set errno on overflow and underflow. @@ -21,7 +21,8 @@ Version 2.23 18966, 18967, 18969, 18970, 18977, 18980, 18981, 18982, 18985, 19003, 19007, 19012, 19016, 19018, 19032, 19046, 19048, 19049, 19050, 19059, 19071, 19074, 19076, 19077, 19078, 19079, 19085, 19086, 19088, 19094, - 19095, 19124, 19125, 19129, 19134, 19137, 19156, 19174, 19181, 19189. + 19095, 19124, 19125, 19129, 19134, 19137, 19156, 19174, 19181, 19189, + 19201. * A defect in the malloc implementation, present since glibc 2.15 (2012) or glibc 2.10 via --enable-experimental-malloc (2009), could result in the diff --git a/math/libm-test.inc b/math/libm-test.inc index 1267b81..2645ccc 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -10318,6 +10318,75 @@ static const struct test_ff_f_data remainder_test_data[] = #if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 56 TEST_ff_f (remainder, -0x1.80000000000002p1L, 2.0, 0x1.fffffffffffff8p-1L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), #endif + + TEST_ff_f (remainder, 3419, 360, 179, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -3419, 360, -179, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, 3419, -360, 179, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -3419, -360, -179, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + + TEST_ff_f (remainder, max_value, max_value, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, max_value, -max_value, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, max_value, min_value, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, max_value, -min_value, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, max_value, min_subnorm_value, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, max_value, -min_subnorm_value, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -max_value, max_value, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -max_value, -max_value, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -max_value, min_value, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -max_value, -min_value, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -max_value, min_subnorm_value, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -max_value, -min_subnorm_value, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, min_value, max_value, min_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, min_value, -max_value, min_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, min_value, min_value, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, min_value, -min_value, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, min_value, min_subnorm_value, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, min_value, -min_subnorm_value, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -min_value, max_value, -min_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -min_value, -max_value, -min_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -min_value, min_value, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -min_value, -min_value, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -min_value, min_subnorm_value, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -min_value, -min_subnorm_value, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, min_subnorm_value, max_value, min_subnorm_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, min_subnorm_value, -max_value, min_subnorm_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, min_subnorm_value, min_value, min_subnorm_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, min_subnorm_value, -min_value, min_subnorm_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, min_subnorm_value, min_subnorm_value, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, min_subnorm_value, -min_subnorm_value, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -min_subnorm_value, max_value, -min_subnorm_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -min_subnorm_value, -max_value, -min_subnorm_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -min_subnorm_value, min_value, -min_subnorm_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -min_subnorm_value, -min_value, -min_subnorm_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -min_subnorm_value, min_subnorm_value, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -min_subnorm_value, -min_subnorm_value, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + + TEST_ff_f (remainder, 1, max_value, 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, 1, -max_value, 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, 1, max_value / 2, 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, 1, -max_value / 2, 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, 1, max_value / 4, 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, 1, -max_value / 4, 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, 1, max_value / 8, 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, 1, -max_value / 8, 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -1, max_value, -1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -1, -max_value, -1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -1, max_value / 2, -1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -1, -max_value / 2, -1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -1, max_value / 4, -1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -1, -max_value / 4, -1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -1, max_value / 8, -1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -1, -max_value / 8, -1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + + TEST_ff_f (remainder, max_value, max_value / 2, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, max_value, -max_value / 2, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -max_value, max_value / 2, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -max_value, -max_value / 2, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + + TEST_ff_f (remainder, 2, 1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, 2, -1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -2, 1, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (remainder, -2, -1, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), }; static void diff --git a/sysdeps/ieee754/dbl-64/e_remainder.c b/sysdeps/ieee754/dbl-64/e_remainder.c index 7f3a02b..4818091 100644 --- a/sysdeps/ieee754/dbl-64/e_remainder.c +++ b/sysdeps/ieee754/dbl-64/e_remainder.c @@ -130,6 +130,8 @@ __ieee754_remainder (double x, double y) d = fabs (z); if (d <= fabs (d - y)) return z; + else if (d == y) + return 0.0 * x; else return (z > 0) ? z - y : z + y; } |