summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2016-07-08 12:45:05 +0000
committerzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2016-07-08 12:45:05 +0000
commitd917ef9abb8667ddc7cfd64b259594003fac0ef1 (patch)
tree0b8d64ade769145379b858502ae6e3b9d880f1de /tests
parent17f4f87999945a296beb38ea2794d9f8b70782da (diff)
downloadmpfr-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.c44
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);