diff options
Diffstat (limited to 'tests/tsub.c')
-rw-r--r-- | tests/tsub.c | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/tests/tsub.c b/tests/tsub.c index a8aee323f..260ca107b 100644 --- a/tests/tsub.c +++ b/tests/tsub.c @@ -630,6 +630,135 @@ check_rounding (void) } } +static void +check_max_almosteven (void) +{ + mpfr_exp_t old_emin, old_emax; + mpfr_exp_t emin[2] = { MPFR_EMIN_MIN, -1000 }; + mpfr_exp_t emax[2] = { MPFR_EMAX_MAX, 1000 }; + int i; + + old_emin = mpfr_get_emin (); + old_emax = mpfr_get_emax (); + + for (i = 0; i < 2; i++) + { + mpfr_t a1, a2, b, c; + mpfr_prec_t p; + int neg, j, rnd; + + set_emin (emin[i]); + set_emax (emax[i]); + + p = MPFR_PREC_MIN + randlimb () % 70; + mpfr_init2 (a1, p); + mpfr_init2 (a2, p); + mpfr_init2 (b, p+1); + mpfr_init2 (c, MPFR_PREC_MIN); + + mpfr_setmax (b, 0); + mpfr_set_ui (c, 1, MPFR_RNDN); + + for (neg = 0; neg < 2; neg++) + { + for (j = 1; j >= 0; j--) + { + mpfr_set_exp (b, __gmpfr_emax - j); + RND_LOOP (rnd) + { + unsigned int flags1, flags2; + int inex1, inex2; + + flags1 = MPFR_FLAGS_INEXACT; + if (rnd == MPFR_RNDN || MPFR_IS_LIKE_RNDZ (rnd, neg)) + { + inex1 = neg ? 1 : -1; + mpfr_setmax (a1, __gmpfr_emax - j); + } + else + { + inex1 = neg ? -1 : 1; + if (j == 0) + { + flags1 |= MPFR_FLAGS_OVERFLOW; + mpfr_set_inf (a1, 1); + } + else + { + mpfr_setmin (a1, __gmpfr_emax); + } + } + MPFR_SET_SIGN (a1, neg ? -1 : 1); + + mpfr_clear_flags (); + inex2 = mpfr_sub (a2, b, c, (mpfr_rnd_t) rnd); + flags2 = __gmpfr_flags; + + if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) && + mpfr_equal_p (a1, a2))) + { + printf ("Error 1 in check_max_almosteven for %s," + " i = %d, j = %d, neg = %d\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), + i, j, neg); + printf (" b = "); + mpfr_dump (b); + printf ("Expected "); + mpfr_dump (a1); + printf (" with inex = %d, flags =", inex1); + flags_out (flags1); + printf ("Got "); + mpfr_dump (a2); + printf (" with inex = %d, flags =", inex2); + flags_out (flags2); + exit (1); + } + + if (i == 0) + break; + + mpfr_clear_flags (); + set_emin (MPFR_EMIN_MIN); + set_emax (MPFR_EMAX_MAX); + inex2 = mpfr_sub (a2, b, c, (mpfr_rnd_t) rnd); + set_emin (emin[i]); + set_emax (emax[i]); + inex2 = mpfr_check_range (a2, inex2, (mpfr_rnd_t) rnd); + flags2 = __gmpfr_flags; + + if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) && + mpfr_equal_p (a1, a2))) + { + printf ("Error 2 in check_max_almosteven for %s," + " i = %d, j = %d, neg = %d\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), + i, j, neg); + printf (" b = "); + mpfr_dump (b); + printf ("Expected "); + mpfr_dump (a1); + printf (" with inex = %d, flags =", inex1); + flags_out (flags1); + printf ("Got "); + mpfr_dump (a2); + printf (" with inex = %d, flags =", inex2); + flags_out (flags2); + exit (1); + } + } + } /* j */ + + mpfr_neg (b, b, MPFR_RNDN); + mpfr_neg (c, c, MPFR_RNDN); + } /* neg */ + + mpfr_clears (a1, a2, b, c, (mpfr_ptr) 0); + } /* i */ + + set_emin (old_emin); + set_emax (old_emax); +} + #define TEST_FUNCTION test_sub #define TWO_ARGS #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS) @@ -647,6 +776,7 @@ main (void) check_rounding (); check_diverse (); check_inexact (); + check_max_almosteven (); bug_ddefour (); for (p=2; p<200; p++) for (i=0; i<50; i++) |