diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2015-06-12 13:38:54 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2015-06-12 13:38:54 +0000 |
commit | d76001096a9b2a769b51cc787fb72e32b9081cd5 (patch) | |
tree | 2fcad587acc8e0c5be29a120651b4e463f853738 /tests | |
parent | 859cb539e22d02bb3ae273bf726af997e73433d9 (diff) | |
download | mpfr-d76001096a9b2a769b51cc787fb72e32b9081cd5.tar.gz |
[src/fma.c] Fixed the scaling in case of underflow. Added log messages.
[tests/tfma.c] Added testcases. Code clean-up.
(merged changesets r9560-9569 from the trunk, with mpfr_flags_t
replaced by unsigned int)
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/branches/3.1@9570 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'tests')
-rw-r--r-- | tests/tfma.c | 222 |
1 files changed, 145 insertions, 77 deletions
diff --git a/tests/tfma.c b/tests/tfma.c index 4709ccced..612f31c9a 100644 --- a/tests/tfma.c +++ b/tests/tfma.c @@ -67,7 +67,7 @@ test_exact (void) i, j, k, rnd); exit (1); } - if (mpfr_cmp (r1, r2) || MPFR_SIGN (r1) != MPFR_SIGN (r2)) + if (! mpfr_equal_p (r1, r2) || MPFR_SIGN (r1) != MPFR_SIGN (r2)) { printf ("test_exact(%d,%d,%d,%d):\nexpected ", i, j, k, rnd); mpfr_out_str (stdout, 10, 0, r1, MPFR_RNDN); @@ -338,6 +338,64 @@ test_underflow2 (void) } static void +test_underflow3 (int n) +{ + mpfr_t x, y, z, t1, t2; + int k, s, rnd, inex1, inex2; + mpfr_exp_t e; + unsigned int flags1, flags2; + + mpfr_inits2 (4, x, z, t1, t2, (mpfr_ptr) 0); + mpfr_init2 (y, 6); + + e = mpfr_get_emin () - 1; + + for (k = 1; k <= 7; k++) + for (s = -1; s <= 1; s++) + { + mpfr_set_si_2exp (x, 1, e, MPFR_RNDN); + mpfr_set_si_2exp (y, 8*k+s, -6, MPFR_RNDN); + mpfr_neg (z, x, MPFR_RNDN); + /* x = 2^(emin-1) + y = (8 * k + s) * 2^(-6) = k / 8 + s * 2^(-6) + z = -2^(emin-1) + FMA(x,y,z) = (k-8) * 2^(emin-4) + s * 2^(emin-7) exactly. + Note: The purpose of the s * 2^(emin-7) term is to yield + double rounding when scaling for k = 4, s != 0, MPFR_RNDN. */ + + RND_LOOP (rnd) + { + mpfr_clear_flags (); + inex1 = mpfr_set_si_2exp (t1, 8*k+s-64, e-6, (mpfr_rnd_t) rnd); + flags1 = __gmpfr_flags; + + mpfr_clear_flags (); + inex2 = mpfr_fma (t2, x, y, z, (mpfr_rnd_t) rnd); + flags2 = __gmpfr_flags; + + if (! (mpfr_equal_p (t1, t2) && + SAME_SIGN (inex1, inex2) && + flags1 == flags2)) + { + printf ("Error in test_underflow3, n = %d, k = %d, s = %d, %s" + "\n", n, k, s, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + printf ("Expected "); + mpfr_dump (t1); + printf (" with inex ~ %d, flags =", inex1); + flags_out (flags1); + printf ("Got "); + mpfr_dump (t2); + printf (" with inex ~ %d, flags =", inex2); + flags_out (flags2); + exit (1); + } + } + } + + mpfr_clears (x, y, z, t1, t2, (mpfr_ptr) 0); +} + +static void bug20101018 (void) { mpfr_t x, y, z, t, u; @@ -354,7 +412,7 @@ bug20101018 (void) mpfr_set_str (z, "0x8.3ffffffffffe3ffp-14443", 16, MPFR_RNDN); mpfr_set_str (t, "0x8.7ffffffffffc7ffp-14444", 16, MPFR_RNDN); i = mpfr_fma (u, x, y, z, MPFR_RNDN); - if (mpfr_cmp (u, t) != 0) + if (! mpfr_equal_p (u, t)) { printf ("Wrong result in bug20101018 (a)\n"); printf ("Expected "); @@ -377,7 +435,7 @@ bug20101018 (void) mpfr_set_str (z, "0x8.fffff80ffffffffp-1551", 16, MPFR_RNDN); mpfr_set_str (t, "0x9.fffff01ffffffffp-1552", 16, MPFR_RNDN); i = mpfr_fma (u, x, y, z, MPFR_RNDN); - if (mpfr_cmp (u, t) != 0) + if (! mpfr_equal_p (u, t)) { printf ("Wrong result in bug20101018 (b)\n"); printf ("Expected "); @@ -400,7 +458,7 @@ bug20101018 (void) mpfr_set_str (z, "0x8p-8119", 16, MPFR_RNDN); mpfr_set_str (t, "0x8.000000000000001p-8120", 16, MPFR_RNDN); i = mpfr_fma (u, x, y, z, MPFR_RNDN); - if (mpfr_cmp (u, t) != 0) + if (! mpfr_equal_p (u, t)) { printf ("Wrong result in bug20101018 (c)\n"); printf ("Expected "); @@ -429,10 +487,13 @@ int main (int argc, char *argv[]) { mpfr_t x, y, z, s; - MPFR_SAVE_EXPO_DECL (expo); + mpfr_exp_t emin, emax; tests_start_mpfr (); + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + bug20101018 (); mpfr_init (x); @@ -612,7 +673,7 @@ main (int argc, char *argv[]) mpfr_urandomb (y, RANDS); mpfr_urandomb (z, RANDS); mpfr_fma (s, x, y, z, MPFR_RNDN); - if (mpfr_cmp (s, z)) + if (! mpfr_equal_p (s, z)) { printf ("evaluation of function in x=0 does not return z\n"); exit (1); @@ -622,7 +683,7 @@ main (int argc, char *argv[]) mpfr_urandomb (x, RANDS); mpfr_urandomb (z, RANDS); mpfr_fma (s, x, y, z, MPFR_RNDN); - if (mpfr_cmp (s, z)) + if (! mpfr_equal_p (s, z)) { printf ("evaluation of function in y=0 does not return z\n"); exit (1); @@ -635,81 +696,79 @@ main (int argc, char *argv[]) int inexact, compare; unsigned int n; - mpfr_prec_t p0=2, p1=200; - unsigned int N=200; + mpfr_prec_t p0 = 2, p1 = 200; + unsigned int N = 200; mpfr_init (t); mpfr_init (slong); /* generic test */ for (prec = p0; prec <= p1; prec++) - { - mpfr_set_prec (x, prec); - mpfr_set_prec (y, prec); - mpfr_set_prec (z, prec); - mpfr_set_prec (s, prec); - mpfr_set_prec (t, prec); + { + mpfr_set_prec (x, prec); + mpfr_set_prec (y, prec); + mpfr_set_prec (z, prec); + mpfr_set_prec (s, prec); + mpfr_set_prec (t, prec); - for (n=0; n<N; n++) - { - mpfr_urandomb (x, RANDS); - mpfr_urandomb (y, RANDS); - mpfr_urandomb (z, RANDS); - - if (randlimb () % 2) - mpfr_neg (x, x, MPFR_RNDN); - if (randlimb () % 2) - mpfr_neg (y, y, MPFR_RNDN); - if (randlimb () % 2) - mpfr_neg (z, z, MPFR_RNDN); - - rnd = RND_RAND (); - mpfr_set_prec (slong, 2 * prec); - if (mpfr_mul (slong, x, y, rnd)) - { - printf ("x*y should be exact\n"); - exit (1); - } - compare = mpfr_add (t, slong, z, rnd); - inexact = mpfr_fma (s, x, y, z, rnd); - if (mpfr_cmp (s, t)) - { - printf ("results differ for x="); - mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN); - printf (" y="); - mpfr_out_str (stdout, 2, prec, y, MPFR_RNDN); - printf (" z="); - mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN); - printf (" prec=%u rnd_mode=%s\n", (unsigned int) prec, - mpfr_print_rnd_mode (rnd)); - printf ("got "); - mpfr_out_str (stdout, 2, prec, s, MPFR_RNDN); - puts (""); - printf ("expected "); - mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN); - puts (""); - printf ("approx "); - mpfr_print_binary (slong); - puts (""); - exit (1); - } - if (((inexact == 0) && (compare != 0)) || - ((inexact < 0) && (compare >= 0)) || - ((inexact > 0) && (compare <= 0))) - { - printf ("Wrong inexact flag for rnd=%s: expected %d, got %d\n", - mpfr_print_rnd_mode (rnd), compare, inexact); - printf (" x="); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); - printf (" y="); mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); - printf (" z="); mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN); - printf (" s="); mpfr_out_str (stdout, 2, 0, s, MPFR_RNDN); - printf ("\n"); - exit (1); - } - } - } - mpfr_clear (t); - mpfr_clear (slong); + for (n = 0; n < N; n++) + { + mpfr_urandomb (x, RANDS); + mpfr_urandomb (y, RANDS); + mpfr_urandomb (z, RANDS); + + if (randlimb () % 2) + mpfr_neg (x, x, MPFR_RNDN); + if (randlimb () % 2) + mpfr_neg (y, y, MPFR_RNDN); + if (randlimb () % 2) + mpfr_neg (z, z, MPFR_RNDN); + + rnd = RND_RAND (); + mpfr_set_prec (slong, 2 * prec); + if (mpfr_mul (slong, x, y, rnd)) + { + printf ("x*y should be exact\n"); + exit (1); + } + compare = mpfr_add (t, slong, z, rnd); + inexact = mpfr_fma (s, x, y, z, rnd); + if (! mpfr_equal_p (s, t)) + { + printf ("results differ for x="); + mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN); + printf (" y="); + mpfr_out_str (stdout, 2, prec, y, MPFR_RNDN); + printf (" z="); + mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN); + printf (" prec=%u rnd_mode=%s\n", (unsigned int) prec, + mpfr_print_rnd_mode (rnd)); + printf ("got "); + mpfr_out_str (stdout, 2, prec, s, MPFR_RNDN); + puts (""); + printf ("expected "); + mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN); + puts (""); + printf ("approx "); + mpfr_print_binary (slong); + puts (""); + exit (1); + } + if (! SAME_SIGN (inexact, compare)) + { + printf ("Wrong inexact flag for rnd=%s: expected %d, got %d\n", + mpfr_print_rnd_mode (rnd), compare, inexact); + printf (" x="); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); + printf (" y="); mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); + printf (" z="); mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN); + printf (" s="); mpfr_out_str (stdout, 2, 0, s, MPFR_RNDN); + printf ("\n"); + exit (1); + } + } + } + mpfr_clear (t); + mpfr_clear (slong); } mpfr_clear (x); @@ -719,12 +778,21 @@ main (int argc, char *argv[]) test_exact (); - MPFR_SAVE_EXPO_MARK (expo); test_overflow1 (); test_overflow2 (); test_underflow1 (); test_underflow2 (); - MPFR_SAVE_EXPO_FREE (expo); + test_underflow3 (1); + + set_emin (MPFR_EMIN_MIN); + set_emax (MPFR_EMAX_MAX); + test_overflow1 (); + test_overflow2 (); + test_underflow1 (); + test_underflow2 (); + test_underflow3 (2); + set_emin (emin); + set_emax (emax); tests_end_mpfr (); return 0; |