summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2020-03-25 16:55:37 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2020-03-25 16:55:37 +0000
commit46dc00d0d215de143caa9a52f9607347d59fa7cb (patch)
tree6d417e219c423e6eabd9bc27f2c1e83be58b68d1
parentc5bab710f0bd0f6d170eb7ce034d8129049ad12c (diff)
downloadmpfr-46dc00d0d215de143caa9a52f9607347d59fa7cb.tar.gz
[tests/tset_si.c] Added tests of mpfr_set_si_2exp and mpfr_set_ui_2exp
in precision 3 with integers from -31 to 31 and exponents MPFR_EXP_MIN, MPFR_EMIN_MIN-7 to MPFR_EMIN_MIN, MPFR_EMAX_MAX-7 to MPFR_EMAX_MAX, MPFR_EXP_MAX-7 to MPFR_EXP_MAX, showing bugs in these functions when MPFR_LONG_WITHIN_LIMB is defined. git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@13808 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r--tests/tset_si.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/tests/tset_si.c b/tests/tset_si.c
index fab36efdb..ce2a5d1f8 100644
--- a/tests/tset_si.c
+++ b/tests/tset_si.c
@@ -90,6 +90,134 @@ test_2exp (void)
mpfr_clear (x);
}
+#define REXP 1024
+
+static void
+test_2exp_extreme_aux (void)
+{
+ mpfr_t x1, x2, y;
+ mpfr_exp_t e, ep[1 + 8 * 5], eb[] =
+ { MPFR_EMIN_MIN, -REXP, REXP, MPFR_EMAX_MAX, MPFR_EXP_MAX };
+ mpfr_flags_t flags1, flags2;
+ int i, j, rnd, inex1, inex2;
+ char s;
+
+ ep[0] = MPFR_EXP_MIN;
+ for (i = 0; i < numberof(eb); i++)
+ for (j = 0; j < 8; j++)
+ ep[1 + 8 * i + j] = eb[i] - j;
+
+ mpfr_inits2 (3, x1, x2, (mpfr_ptr) 0);
+ mpfr_init2 (y, 32);
+
+ for (i = 0; i < numberof(ep); i++)
+ for (j = -31; j <= 31; j++)
+ RND_LOOP_NO_RNDF (rnd)
+ {
+ int sign = j < 0 ? -1 : 1;
+
+ /* Compute the expected value, inex and flags */
+ inex1 = mpfr_set_si (y, j, MPFR_RNDN);
+ MPFR_ASSERTN (inex1 == 0);
+ inex1 = mpfr_set (x1, y, (mpfr_rnd_t) rnd);
+ /* x1 is the rounded value and inex1 the ternary value,
+ assuming that the exponent argument is 0 (this is the
+ rounded significand of the final result, assuming an
+ unbounded exponent range). The multiplication by a
+ power of 2 is exact, unless underflow/overflow occurs.
+ The tests on the exponent below avoid integer overflows
+ (ep[i] may take extreme values). */
+ e = mpfr_get_exp (x1);
+ mpfr_clear_flags ();
+ if (j != 0 && ep[i] < __gmpfr_emin - e) /* underflow */
+ {
+ mpfr_rnd_t r =
+ (rnd == MPFR_RNDN &&
+ (ep[i] < __gmpfr_emin - mpfr_get_exp (y) - 1 ||
+ IS_POW2 (sign * j))) ?
+ MPFR_RNDZ : (mpfr_rnd_t) rnd;
+ inex1 = mpfr_underflow (x1, r, sign);
+ flags1 = __gmpfr_flags;
+ }
+ else if (j != 0 && ep[i] > __gmpfr_emax - e) /* overflow */
+ {
+ inex1 = mpfr_overflow (x1, (mpfr_rnd_t) rnd, sign);
+ flags1 = __gmpfr_flags;
+ }
+ else
+ {
+ if (j != 0)
+ mpfr_set_exp (x1, ep[i] + e);
+ flags1 = inex1 != 0 ? MPFR_FLAGS_INEXACT : 0;
+ }
+
+ /* Test mpfr_set_si_2exp */
+ mpfr_clear_flags ();
+ inex2 = mpfr_set_si_2exp (x2, j, ep[i], (mpfr_rnd_t) rnd);
+ flags2 = __gmpfr_flags;
+
+ if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
+ mpfr_equal_p (x1, x2)))
+ {
+ s = 's';
+ goto err_extreme;
+ }
+
+ if (j < 0)
+ continue;
+
+ /* Test mpfr_set_ui_2exp */
+ mpfr_clear_flags ();
+ inex2 = mpfr_set_ui_2exp (x2, j, ep[i], (mpfr_rnd_t) rnd);
+ flags2 = __gmpfr_flags;
+
+ if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
+ mpfr_equal_p (x1, x2)))
+ {
+ s = 'u';
+ err_extreme:
+ printf ("Error in extreme mpfr_set_%ci_2exp for i=%d j=%d %s\n",
+ s, i, j, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ printf ("emin=%" MPFR_EXP_FSPEC "d "
+ "emax=%" MPFR_EXP_FSPEC "d\n",
+ (mpfr_eexp_t) __gmpfr_emin,
+ (mpfr_eexp_t) __gmpfr_emax);
+ printf ("ep[%d] = %" MPFR_EXP_FSPEC "d\n", i, ep[i]);
+ printf ("Expected ");
+ mpfr_dump (x1);
+ printf ("with inex = %d and flags =", inex1);
+ flags_out (flags1);
+ printf ("Got ");
+ mpfr_dump (x2);
+ printf ("with inex = %d and flags =", inex2);
+ flags_out (flags2);
+ exit (1);
+ }
+ }
+
+ mpfr_clears (x1, x2, y, (mpfr_ptr) 0);
+}
+
+static void
+test_2exp_extreme (void)
+{
+ mpfr_exp_t emin, emax;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+
+ set_emin (MPFR_EMIN_MIN);
+ set_emax (MPFR_EMAX_MAX);
+ test_2exp_extreme_aux ();
+
+ set_emin (-REXP);
+ set_emax (REXP);
+ test_2exp_extreme_aux ();
+
+ set_emin (emin);
+ set_emax (emax);
+}
+
static void
test_macros (void)
{
@@ -639,6 +767,7 @@ main (int argc, char *argv[])
mpfr_clear (x);
test_2exp ();
+ test_2exp_extreme ();
test_macros ();
test_macros_keyword ();
test_get_ui_smallneg ();