diff options
author | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2016-07-08 12:45:05 +0000 |
---|---|---|
committer | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2016-07-08 12:45:05 +0000 |
commit | d917ef9abb8667ddc7cfd64b259594003fac0ef1 (patch) | |
tree | 0b8d64ade769145379b858502ae6e3b9d880f1de /tests | |
parent | 17f4f87999945a296beb38ea2794d9f8b70782da (diff) | |
download | mpfr-d917ef9abb8667ddc7cfd64b259594003fac0ef1.tar.gz |
[tests/tmul.c] added underflow test for directed rounding too
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@10602 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'tests')
-rw-r--r-- | tests/tmul.c | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/tests/tmul.c b/tests/tmul.c index 1556a0029..c5472c466 100644 --- a/tests/tmul.c +++ b/tests/tmul.c @@ -632,7 +632,7 @@ test_underflow (mpfr_prec_t pmax) mpfr_t a, b, c; int inex; - /* we want b*c < 0.5*2^emin but round(b*c, p) >= 0.5*2^emin thus + /* for RNDN, we want b*c < 0.5*2^emin but round(b*c, p) = 0.5*2^emin thus b*c >= (0.5 - 1/4*ulp_p(0.5))*2^emin */ for (p = MPFR_PREC_MIN; p <= pmax; p++) { @@ -646,15 +646,49 @@ test_underflow (mpfr_prec_t pmax) /* 0.5 - 1/4*ulp_p(0.5) <= b * c < 0.5 */ mpfr_mul_2si (b, b, mpfr_get_emin () / 2, MPFR_RNDZ); mpfr_mul_2si (c, c, (mpfr_get_emin () - 1) / 2, MPFR_RNDZ); - if (inex) - mpfr_nextabove (c); mpfr_set_prec (a, p); mpfr_clear_underflow (); mpfr_mul (a, b, c, MPFR_RNDN); if (!mpfr_zero_p (a) && mpfr_underflow_p ()) { - printf ("Error, underflow flag incorrectly set for emin=%ld\n", - mpfr_get_emin ()); + printf ("Error, underflow flag incorrectly set for emin=%ld, rnd=%s\n", + mpfr_get_emin (), mpfr_print_rnd_mode (MPFR_RNDN)); + printf ("b="); mpfr_dump (b); + printf ("c="); mpfr_dump (c); + printf ("a="); mpfr_dump (a); + mpfr_set_prec (a, mpfr_get_prec (b) + mpfr_get_prec (c)); + mpfr_mul_2exp (b, b, 1, MPFR_RNDN); + mpfr_mul (a, b, c, MPFR_RNDN); + printf ("2*a="); mpfr_dump (a); + exit (1); + } + mpfr_clear (a); + mpfr_clear (b); + mpfr_clear (c); + } + + /* for RNDU, we want b*c < 0.5*2^emin but round(b*c, p) = 0.5*2^emin thus + b*c > (0.5 - 1/2*ulp_p(0.5))*2^emin */ + for (p = MPFR_PREC_MIN; p <= pmax; p++) + { + mpfr_init2 (a, p); + mpfr_init2 (b, p + 10); + mpfr_init2 (c, p + 10); + mpfr_urandomb (b, RANDS); + mpfr_set_ui_2exp (a, 1, -1, MPFR_RNDZ); /* a = 0.5 */ + mpfr_nextbelow (a); /* 0.5 - 1/2*ulp_p(0.5) */ + inex = mpfr_div (c, a, b, MPFR_RNDU); + /* 0.5 - 1/2*ulp_p(0.5) <= b * c < 0.5 */ + mpfr_mul_2si (b, b, mpfr_get_emin () / 2, MPFR_RNDZ); + mpfr_mul_2si (c, c, (mpfr_get_emin () - 1) / 2, MPFR_RNDZ); + if (inex) + mpfr_nextabove (c); /* ensures that b*c > (0.5 - 1/2*ulp_p(0.5))*2^emin */ + mpfr_clear_underflow (); + mpfr_mul (a, b, c, MPFR_RNDN); + if (!mpfr_zero_p (a) && mpfr_underflow_p ()) + { + printf ("Error, underflow flag incorrectly set for emin=%ld, rnd=%s\n", + mpfr_get_emin (), mpfr_print_rnd_mode (MPFR_RNDU)); printf ("b="); mpfr_dump (b); printf ("c="); mpfr_dump (c); printf ("a="); mpfr_dump (a); |