summaryrefslogtreecommitdiff
path: root/tests/tmul.c
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2017-01-09 14:03:01 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2017-01-09 14:03:01 +0000
commited9d33db1c0cecb5aa9b92567fbbbb5a491793d7 (patch)
treea36b357d3ff26926423d06698f65fa4524c56cce /tests/tmul.c
parent5e8e05cb87e0c59ac02eec68d0210086c337092e (diff)
downloadmpfr-ed9d33db1c0cecb5aa9b92567fbbbb5a491793d7.tar.gz
Merged the latest changes from the trunk (changing a RND_RAND to
RND_RAND_NO_RNDF in order to avoid a failure in a test). git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/branches/faithful@11168 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'tests/tmul.c')
-rw-r--r--tests/tmul.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/tests/tmul.c b/tests/tmul.c
index 046c1ace0..0c18e07f7 100644
--- a/tests/tmul.c
+++ b/tests/tmul.c
@@ -910,6 +910,110 @@ bug20161209a (void)
set_emin (emin);
}
+/* Test for 1 to 3 limbs. */
+static void
+small_prec (void)
+{
+ mpfr_exp_t emin, emax;
+ mpfr_t x, y, z1, z2, zz;
+ int xq, yq, zq;
+ mpfr_rnd_t rnd;
+ mpfr_flags_t flags1, flags2;
+ int inex1, inex2;
+ int i, j, r, s, ediff;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+
+ /* The mpfr_mul implementation doesn't extend the exponent range,
+ so that it is OK to reduce it here for the test to make sure that
+ mpfr_mul_2si can be used. */
+ set_emin (-1000);
+ set_emax (1000);
+
+ mpfr_inits2 (3 * GMP_NUMB_BITS, x, y, z1, z2, (mpfr_ptr) 0);
+ mpfr_init2 (zz, 6 * GMP_NUMB_BITS);
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 10000; j++)
+ {
+ xq = i * GMP_NUMB_BITS + 1 + randlimb () % GMP_NUMB_BITS;
+ mpfr_set_prec (x, xq);
+ yq = i * GMP_NUMB_BITS + 1 + randlimb () % GMP_NUMB_BITS;
+ mpfr_set_prec (y, yq);
+ zq = i * GMP_NUMB_BITS + 1 + randlimb () % (GMP_NUMB_BITS-1);
+ mpfr_set_prec (z1, zq);
+ mpfr_set_prec (z2, zq);
+ s = r = randlimb () & 0x7f;
+ do mpfr_urandomb (x, RANDS); while (mpfr_zero_p (x));
+ if (s & 1)
+ mpfr_neg (x, x, MPFR_RNDN);
+ s >>= 1;
+ if (s & 1)
+ {
+ do mpfr_urandomb (y, RANDS); while (mpfr_zero_p (y));
+ }
+ else
+ {
+ mpfr_ui_div (y, 1, x, MPFR_RNDN);
+ mpfr_set_exp (y, 0);
+ }
+ s >>= 1;
+ if (s & 1)
+ mpfr_neg (y, y, MPFR_RNDN);
+ s >>= 1;
+ rnd = RND_RAND_NO_RNDF ();
+ inex1 = mpfr_mul (zz, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (inex1 == 0);
+ if (s == 0)
+ {
+ ediff = __gmpfr_emin - MPFR_EXP (x);
+ mpfr_set_exp (x, __gmpfr_emin);
+ }
+ else if (s == 1)
+ {
+ ediff = __gmpfr_emax - MPFR_EXP (x) + 1;
+ mpfr_set_exp (x, __gmpfr_emax);
+ mpfr_mul_2ui (y, y, 1, MPFR_RNDN);
+ }
+ else
+ ediff = 0;
+ mpfr_clear_flags ();
+ inex1 = mpfr_mul_2si (z1, zz, ediff, rnd);
+ flags1 = __gmpfr_flags;
+ mpfr_clear_flags ();
+ inex2 = mpfr_mul (z2, x, y, rnd);
+ flags2 = __gmpfr_flags;
+ if (!(mpfr_equal_p (z1, z2) &&
+ SAME_SIGN (inex1, inex2) &&
+ flags1 == flags2))
+ {
+ printf ("Error in small_prec on i = %d, j = %d\n", i, j);
+ printf ("r = 0x%x, xq = %d, yq = %d, zq = %d, rnd = %s\n",
+ r, xq, yq, zq, mpfr_print_rnd_mode (rnd));
+ printf ("x = ");
+ mpfr_dump (x);
+ printf ("y = ");
+ mpfr_dump (y);
+ printf ("ediff = %d\n", ediff);
+ printf ("zz = ");
+ mpfr_dump (zz);
+ printf ("Expected ");
+ mpfr_dump (z1);
+ printf ("with inex = %d and flags =", inex1);
+ flags_out (flags1);
+ printf ("Got ");
+ mpfr_dump (z2);
+ printf ("with inex = %d and flags =", inex2);
+ flags_out (flags2);
+ exit (1);
+ }
+ }
+ mpfr_clears (x, y, z1, z2, zz, (mpfr_ptr) 0);
+
+ set_emin (emin);
+ set_emax (emax);
+}
+
int
main (int argc, char *argv[])
{
@@ -951,6 +1055,7 @@ main (int argc, char *argv[])
49, 3, 2, "0.09375");
check_max();
check_min();
+ small_prec ();
check_regression ();
test_generic (MPFR_PREC_MIN, 500, 100);