Fix remainder exceptions and directed-rounding results (bugs 15480, 15485).
This commit is contained in:
parent
a00bdcf0e0
commit
bb38759d6d
17
ChangeLog
17
ChangeLog
@ -1,5 +1,22 @@
|
|||||||
2013-05-17 Joseph Myers <joseph@codesourcery.com>
|
2013-05-17 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
|
[BZ #15480]
|
||||||
|
[BZ #15485]
|
||||||
|
* sysdeps/ieee754/dbl-64/e_remainder.c (__ieee754_remainder): For
|
||||||
|
main case of finite arguments, set rounding mode to FE_TONEAREST
|
||||||
|
and discard exceptions.
|
||||||
|
* math/libm-test.inc (remainder_test_data): Disallow "inexact"
|
||||||
|
exceptions.
|
||||||
|
(remainder_tonearest_test_data): New variable.
|
||||||
|
(remainder_test_tonearest): New function.
|
||||||
|
(remainder_towardzero_test_data): New variable.
|
||||||
|
(remainder_test_towardzero): New function.
|
||||||
|
(remainder_downward_test_data): New variable.
|
||||||
|
(remainder_test_downward): New function.
|
||||||
|
(remainder_upward_test_data): New variable.
|
||||||
|
(remainder_test_upward): New function.
|
||||||
|
(main): Call the new test functions.
|
||||||
|
|
||||||
* math/libm-test.inc (struct test_f_f1_data): Remove field
|
* math/libm-test.inc (struct test_f_f1_data): Remove field
|
||||||
extra_init.
|
extra_init.
|
||||||
(struct test_fF_f1_data): Likewise.
|
(struct test_fF_f1_data): Likewise.
|
||||||
|
2
NEWS
2
NEWS
@ -17,7 +17,7 @@ Version 2.18
|
|||||||
15086, 15160, 15214, 15221, 15232, 15234, 15283, 15285, 15287, 15304,
|
15086, 15160, 15214, 15221, 15232, 15234, 15283, 15285, 15287, 15304,
|
||||||
15305, 15307, 15309, 15327, 15330, 15335, 15336, 15337, 15342, 15346,
|
15305, 15307, 15309, 15327, 15330, 15335, 15336, 15337, 15342, 15346,
|
||||||
15359, 15361, 15366, 15380, 15394, 15395, 15405, 15406, 15409, 15416,
|
15359, 15361, 15366, 15380, 15394, 15395, 15405, 15406, 15409, 15416,
|
||||||
15418, 15419, 15423, 15424, 15426, 15429, 15442, 15448.
|
15418, 15419, 15423, 15424, 15426, 15429, 15442, 15448, 15480, 15485.
|
||||||
|
|
||||||
* CVE-2013-0242 Buffer overrun in regexp matcher has been fixed (Bugzilla
|
* CVE-2013-0242 Buffer overrun in regexp matcher has been fixed (Bugzilla
|
||||||
#15078).
|
#15078).
|
||||||
|
@ -12276,13 +12276,12 @@ static const struct test_ff_f_data remainder_test_data[] =
|
|||||||
TEST_ff_f (remainder, 7.0, plus_infty, 7.0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
TEST_ff_f (remainder, 7.0, plus_infty, 7.0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
TEST_ff_f (remainder, 7.0, minus_infty, 7.0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
TEST_ff_f (remainder, 7.0, minus_infty, 7.0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
|
|
||||||
/* Bug 15480: spurious "inexact" exception may occur. */
|
TEST_ff_f (remainder, 1.625, 1.0, -0.375, NO_INEXACT_EXCEPTION),
|
||||||
TEST_ff_f (remainder, 1.625, 1.0, -0.375),
|
TEST_ff_f (remainder, -1.625, 1.0, 0.375, NO_INEXACT_EXCEPTION),
|
||||||
TEST_ff_f (remainder, -1.625, 1.0, 0.375),
|
TEST_ff_f (remainder, 1.625, -1.0, -0.375, NO_INEXACT_EXCEPTION),
|
||||||
TEST_ff_f (remainder, 1.625, -1.0, -0.375),
|
TEST_ff_f (remainder, -1.625, -1.0, 0.375, NO_INEXACT_EXCEPTION),
|
||||||
TEST_ff_f (remainder, -1.625, -1.0, 0.375),
|
TEST_ff_f (remainder, 5.0, 2.0, 1.0, NO_INEXACT_EXCEPTION),
|
||||||
TEST_ff_f (remainder, 5.0, 2.0, 1.0),
|
TEST_ff_f (remainder, 3.0, 2.0, -1.0, NO_INEXACT_EXCEPTION),
|
||||||
TEST_ff_f (remainder, 3.0, 2.0, -1.0),
|
|
||||||
END_DATA (remainder)
|
END_DATA (remainder)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -12294,6 +12293,158 @@ remainder_test (void)
|
|||||||
END (remainder);
|
END (remainder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const struct test_ff_f_data remainder_tonearest_test_data[] =
|
||||||
|
{
|
||||||
|
START_DATA (remainder_tonearest),
|
||||||
|
TEST_ff_f (remainder, 1, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, 1, minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, plus_infty, minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, plus_infty, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, plus_infty, 1, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, plus_infty, 2, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, minus_infty, minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, minus_infty, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, minus_infty, 1, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, minus_infty, 2, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
|
TEST_ff_f (remainder, 0, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
|
TEST_ff_f (remainder, qnan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
|
|
||||||
|
TEST_ff_f (remainder, 7.0, plus_infty, 7.0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
|
TEST_ff_f (remainder, 7.0, minus_infty, 7.0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
|
|
||||||
|
TEST_ff_f (remainder, 1.625, 1.0, -0.375, NO_INEXACT_EXCEPTION),
|
||||||
|
TEST_ff_f (remainder, -1.625, 1.0, 0.375, NO_INEXACT_EXCEPTION),
|
||||||
|
TEST_ff_f (remainder, 1.625, -1.0, -0.375, NO_INEXACT_EXCEPTION),
|
||||||
|
TEST_ff_f (remainder, -1.625, -1.0, 0.375, NO_INEXACT_EXCEPTION),
|
||||||
|
TEST_ff_f (remainder, 5.0, 2.0, 1.0, NO_INEXACT_EXCEPTION),
|
||||||
|
TEST_ff_f (remainder, 3.0, 2.0, -1.0, NO_INEXACT_EXCEPTION),
|
||||||
|
END_DATA (remainder_tonearest)
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
remainder_test_tonearest (void)
|
||||||
|
{
|
||||||
|
START (remainder_tonearest);
|
||||||
|
RUN_TEST_LOOP_ff_f (remainder, remainder_tonearest_test_data, FE_TONEAREST);
|
||||||
|
END (remainder_tonearest);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const struct test_ff_f_data remainder_towardzero_test_data[] =
|
||||||
|
{
|
||||||
|
START_DATA (remainder_towardzero),
|
||||||
|
TEST_ff_f (remainder, 1, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, 1, minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, plus_infty, minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, plus_infty, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, plus_infty, 1, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, plus_infty, 2, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, minus_infty, minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, minus_infty, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, minus_infty, 1, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, minus_infty, 2, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
|
TEST_ff_f (remainder, 0, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
|
TEST_ff_f (remainder, qnan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
|
|
||||||
|
TEST_ff_f (remainder, 7.0, plus_infty, 7.0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
|
TEST_ff_f (remainder, 7.0, minus_infty, 7.0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
|
|
||||||
|
TEST_ff_f (remainder, 1.625, 1.0, -0.375, NO_INEXACT_EXCEPTION),
|
||||||
|
TEST_ff_f (remainder, -1.625, 1.0, 0.375, NO_INEXACT_EXCEPTION),
|
||||||
|
TEST_ff_f (remainder, 1.625, -1.0, -0.375, NO_INEXACT_EXCEPTION),
|
||||||
|
TEST_ff_f (remainder, -1.625, -1.0, 0.375, NO_INEXACT_EXCEPTION),
|
||||||
|
TEST_ff_f (remainder, 5.0, 2.0, 1.0, NO_INEXACT_EXCEPTION),
|
||||||
|
TEST_ff_f (remainder, 3.0, 2.0, -1.0, NO_INEXACT_EXCEPTION),
|
||||||
|
END_DATA (remainder_towardzero)
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
remainder_test_towardzero (void)
|
||||||
|
{
|
||||||
|
START (remainder_towardzero);
|
||||||
|
RUN_TEST_LOOP_ff_f (remainder, remainder_towardzero_test_data, FE_TOWARDZERO);
|
||||||
|
END (remainder_towardzero);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const struct test_ff_f_data remainder_downward_test_data[] =
|
||||||
|
{
|
||||||
|
START_DATA (remainder_downward),
|
||||||
|
TEST_ff_f (remainder, 1, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, 1, minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, plus_infty, minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, plus_infty, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, plus_infty, 1, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, plus_infty, 2, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, minus_infty, minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, minus_infty, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, minus_infty, 1, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, minus_infty, 2, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
|
TEST_ff_f (remainder, 0, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
|
TEST_ff_f (remainder, qnan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
|
|
||||||
|
TEST_ff_f (remainder, 7.0, plus_infty, 7.0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
|
TEST_ff_f (remainder, 7.0, minus_infty, 7.0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
|
|
||||||
|
TEST_ff_f (remainder, 1.625, 1.0, -0.375, NO_INEXACT_EXCEPTION),
|
||||||
|
TEST_ff_f (remainder, -1.625, 1.0, 0.375, NO_INEXACT_EXCEPTION),
|
||||||
|
TEST_ff_f (remainder, 1.625, -1.0, -0.375, NO_INEXACT_EXCEPTION),
|
||||||
|
TEST_ff_f (remainder, -1.625, -1.0, 0.375, NO_INEXACT_EXCEPTION),
|
||||||
|
TEST_ff_f (remainder, 5.0, 2.0, 1.0, NO_INEXACT_EXCEPTION),
|
||||||
|
TEST_ff_f (remainder, 3.0, 2.0, -1.0, NO_INEXACT_EXCEPTION),
|
||||||
|
END_DATA (remainder_downward)
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
remainder_test_downward (void)
|
||||||
|
{
|
||||||
|
START (remainder_downward);
|
||||||
|
RUN_TEST_LOOP_ff_f (remainder, remainder_downward_test_data, FE_DOWNWARD);
|
||||||
|
END (remainder_downward);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const struct test_ff_f_data remainder_upward_test_data[] =
|
||||||
|
{
|
||||||
|
START_DATA (remainder_upward),
|
||||||
|
TEST_ff_f (remainder, 1, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, 1, minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, plus_infty, minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, plus_infty, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, plus_infty, 1, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, plus_infty, 2, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, minus_infty, minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, minus_infty, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, minus_infty, 1, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, minus_infty, 2, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
|
||||||
|
TEST_ff_f (remainder, qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
|
TEST_ff_f (remainder, 0, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
|
TEST_ff_f (remainder, qnan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
|
|
||||||
|
TEST_ff_f (remainder, 7.0, plus_infty, 7.0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
|
TEST_ff_f (remainder, 7.0, minus_infty, 7.0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||||
|
|
||||||
|
TEST_ff_f (remainder, 1.625, 1.0, -0.375, NO_INEXACT_EXCEPTION),
|
||||||
|
TEST_ff_f (remainder, -1.625, 1.0, 0.375, NO_INEXACT_EXCEPTION),
|
||||||
|
TEST_ff_f (remainder, 1.625, -1.0, -0.375, NO_INEXACT_EXCEPTION),
|
||||||
|
TEST_ff_f (remainder, -1.625, -1.0, 0.375, NO_INEXACT_EXCEPTION),
|
||||||
|
TEST_ff_f (remainder, 5.0, 2.0, 1.0, NO_INEXACT_EXCEPTION),
|
||||||
|
TEST_ff_f (remainder, 3.0, 2.0, -1.0, NO_INEXACT_EXCEPTION),
|
||||||
|
END_DATA (remainder_upward)
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
remainder_test_upward (void)
|
||||||
|
{
|
||||||
|
START (remainder_upward);
|
||||||
|
RUN_TEST_LOOP_ff_f (remainder, remainder_upward_test_data, FE_UPWARD);
|
||||||
|
END (remainder_upward);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct test_ffI_f1_data remquo_test_data[] =
|
static const struct test_ffI_f1_data remquo_test_data[] =
|
||||||
{
|
{
|
||||||
START_DATA (remquo),
|
START_DATA (remquo),
|
||||||
@ -14766,6 +14917,10 @@ main (int argc, char **argv)
|
|||||||
/* Remainder functions: */
|
/* Remainder functions: */
|
||||||
fmod_test ();
|
fmod_test ();
|
||||||
remainder_test ();
|
remainder_test ();
|
||||||
|
remainder_test_tonearest ();
|
||||||
|
remainder_test_towardzero ();
|
||||||
|
remainder_test_downward ();
|
||||||
|
remainder_test_upward ();
|
||||||
remquo_test ();
|
remquo_test ();
|
||||||
|
|
||||||
/* Manipulation functions: */
|
/* Manipulation functions: */
|
||||||
|
@ -51,6 +51,7 @@ double __ieee754_remainder(double x, double y)
|
|||||||
ky=t.i[HIGH_HALF];
|
ky=t.i[HIGH_HALF];
|
||||||
/*------ |x| < 2^1023 and 2^-970 < |y| < 2^1024 ------------------*/
|
/*------ |x| < 2^1023 and 2^-970 < |y| < 2^1024 ------------------*/
|
||||||
if (kx<0x7fe00000 && ky<0x7ff00000 && ky>=0x03500000) {
|
if (kx<0x7fe00000 && ky<0x7ff00000 && ky>=0x03500000) {
|
||||||
|
SET_RESTORE_ROUND_NOEX (FE_TONEAREST);
|
||||||
if (kx+0x00100000<ky) return x;
|
if (kx+0x00100000<ky) return x;
|
||||||
if ((kx-0x01500000)<ky) {
|
if ((kx-0x01500000)<ky) {
|
||||||
z=x/t.x;
|
z=x/t.x;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user