summaryrefslogtreecommitdiff
path: root/tests/tgeneric.c
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2015-06-10 10:41:54 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2015-06-10 10:41:54 +0000
commit47f9890b88d607718fbc20088840e8de602b19fb (patch)
tree686e9c313290fdfffc3730025ad41d65064ab2ee /tests/tgeneric.c
parented7872ddd952612fd083252fabe19063b80b6690 (diff)
downloadmpfr-47f9890b88d607718fbc20088840e8de602b19fb.tar.gz
[tests/tgeneric.c] Added overflow/underflow tests. Check whether the
exponent range has been modified by the tested function (which should never happen). (merged/ported changesets r9539,9541,9544 from the trunk) git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/branches/3.1@9546 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'tests/tgeneric.c')
-rw-r--r--tests/tgeneric.c283
1 files changed, 198 insertions, 85 deletions
diff --git a/tests/tgeneric.c b/tests/tgeneric.c
index 8fbbd82c5..1a7315cb1 100644
--- a/tests/tgeneric.c
+++ b/tests/tgeneric.c
@@ -146,6 +146,7 @@ test_generic (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int nmax)
int inexact, compare, compare2;
unsigned int n;
unsigned long ctrt = 0, ctrn = 0;
+ int test_of = 1, test_uf = 1;
mpfr_exp_t old_emin, old_emax;
old_emin = mpfr_get_emin ();
@@ -170,6 +171,7 @@ test_generic (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int nmax)
{
int infinite_input = 0;
unsigned int flags;
+ mpfr_exp_t oemin, oemax;
xprec = prec;
if (randlimb () & 1)
@@ -242,6 +244,10 @@ test_generic (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int nmax)
MPFR_ASSERTN (inexact == 0);
#endif
+ /* Exponent range for the test. */
+ oemin = mpfr_get_emin ();
+ oemax = mpfr_get_emax ();
+
rnd = RND_RAND ();
mpfr_clear_flags ();
#ifdef DEBUG_TGENERIC
@@ -267,104 +273,211 @@ test_generic (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int nmax)
compare = TEST_FUNCTION (y, x, rnd);
#endif
flags = __gmpfr_flags;
+ if (mpfr_get_emin () != oemin ||
+ mpfr_get_emax () != oemax)
+ {
+ printf ("tgeneric: the exponent range has been modified"
+ " by the tested function!\n");
+ exit (1);
+ }
TGENERIC_CHECK ("bad inexact flag",
(compare != 0) ^ (mpfr_inexflag_p () == 0));
ctrt++;
- /* Consistency test in a reduced exponent range. Doing it
- for the first 10 samples and for prec == p1 (which has
- some special cases) should be sufficient. */
- if (ctrt <= 10 || prec == p1)
- {
- unsigned int oldflags = flags;
- mpfr_exp_t e, emin, emax, oemin, oemax;
-
- /* Determine the smallest exponent range containing the
- exponents of the mpfr_t inputs (x, and u if TWO_ARGS)
- and output (y). */
- emin = MPFR_EMAX_MAX;
- emax = MPFR_EMIN_MIN;
- if (MPFR_IS_PURE_FP (x))
- {
- e = MPFR_GET_EXP (x);
- if (e < emin)
- emin = e;
- if (e > emax)
- emax = e;
- }
- if (MPFR_IS_PURE_FP (y))
- {
- e = MPFR_GET_EXP (y);
- if (e < emin)
- emin = e;
- if (e > emax)
- emax = e;
- }
+
+ /* Tests in a reduced exponent range. */
+ {
+ unsigned int oldflags = flags;
+ mpfr_exp_t e, emin, emax;
+
+ /* Determine the smallest exponent range containing the
+ exponents of the mpfr_t inputs (x, and u if TWO_ARGS)
+ and output (y). */
+ emin = MPFR_EMAX_MAX;
+ emax = MPFR_EMIN_MIN;
+ if (MPFR_IS_PURE_FP (x))
+ {
+ e = MPFR_GET_EXP (x);
+ if (e < emin)
+ emin = e;
+ if (e > emax)
+ emax = e;
+ }
#if defined(TWO_ARGS)
- if (MPFR_IS_PURE_FP (u))
- {
- e = MPFR_GET_EXP (u);
- if (e < emin)
- emin = e;
- if (e > emax)
- emax = e;
- }
-#endif
- if (emin > emax)
- emin = emax; /* case where all values are singular */
- oemin = mpfr_get_emin ();
- oemax = mpfr_get_emax ();
- mpfr_set_emin (emin);
- mpfr_set_emax (emax);
+ if (MPFR_IS_PURE_FP (u))
+ {
+ e = MPFR_GET_EXP (u);
+ if (e < emin)
+ emin = e;
+ if (e > emax)
+ emax = e;
+ }
+#endif
+ if (MPFR_IS_PURE_FP (y))
+ {
+ e = MPFR_GET_EXP (y);
+ if (test_of && e - 1 >= emax)
+ {
+ unsigned int ex_flags;
+
+ mpfr_set_emax (e - 1);
+ mpfr_clear_flags ();
+#if defined(TWO_ARGS)
+ inexact = TEST_FUNCTION (w, x, u, rnd);
+#elif defined(DOUBLE_ARG1)
+ inexact = TEST_FUNCTION (w, d, x, rnd);
+#elif defined(DOUBLE_ARG2)
+ inexact = TEST_FUNCTION (w, x, d, rnd);
+#elif defined(ULONG_ARG1)
+ inexact = TEST_FUNCTION (w, i, x, rnd);
+#elif defined(ULONG_ARG2)
+ inexact = TEST_FUNCTION (w, x, i, rnd);
+#else
+ inexact = TEST_FUNCTION (w, x, rnd);
+#endif
+ flags = __gmpfr_flags;
+ mpfr_set_emax (oemax);
+ ex_flags = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT;
+ if (flags != ex_flags)
+ {
+ printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
+ ", reduced exponent range [%"
+ MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC
+ "d] (overflow test) on:\n",
+ (mpfr_eexp_t) oemin, (mpfr_eexp_t) e - 1);
+ printf ("x = ");
+ mpfr_dump (x);
+#if defined(TWO_ARGS_ALL)
+ printf ("u = ");
+ mpfr_dump (u);
+#endif
+ printf ("yprec = %u, rnd_mode = %s\n",
+ (unsigned int) yprec,
+ mpfr_print_rnd_mode (rnd));
+ printf ("Expected flags =");
+ flags_out (ex_flags);
+ printf (" got flags =");
+ flags_out (flags);
+ printf ("inex = %d, w = ", inexact);
+ mpfr_dump (w);
+ exit (1);
+ }
+ test_of = 0; /* Overflow is tested only once. */
+ }
+ if (test_uf && e + 1 <= emin)
+ {
+ unsigned int ex_flags;
+
+ mpfr_set_emin (e + 1);
+ mpfr_clear_flags ();
+#if defined(TWO_ARGS)
+ inexact = TEST_FUNCTION (w, x, u, rnd);
+#elif defined(DOUBLE_ARG1)
+ inexact = TEST_FUNCTION (w, d, x, rnd);
+#elif defined(DOUBLE_ARG2)
+ inexact = TEST_FUNCTION (w, x, d, rnd);
+#elif defined(ULONG_ARG1)
+ inexact = TEST_FUNCTION (w, i, x, rnd);
+#elif defined(ULONG_ARG2)
+ inexact = TEST_FUNCTION (w, x, i, rnd);
+#else
+ inexact = TEST_FUNCTION (w, x, rnd);
+#endif
+ flags = __gmpfr_flags;
+ mpfr_set_emin (oemin);
+ ex_flags = MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT;
+ if (flags != ex_flags)
+ {
+ printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
+ ", reduced exponent range [%"
+ MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC
+ "d] (underflow test) on:\n",
+ (mpfr_eexp_t) e + 1, (mpfr_eexp_t) oemax);
+ printf ("x = ");
+ mpfr_dump (x);
+#if defined(TWO_ARGS_ALL)
+ printf ("u = ");
+ mpfr_dump (u);
+#endif
+ printf ("yprec = %u, rnd_mode = %s\n",
+ (unsigned int) yprec,
+ mpfr_print_rnd_mode (rnd));
+ printf ("Expected flags =");
+ flags_out (ex_flags);
+ printf (" got flags =");
+ flags_out (flags);
+ printf ("inex = %d, w = ", inexact);
+ mpfr_dump (w);
+ exit (1);
+ }
+ test_uf = 0; /* Underflow is tested only once. */
+ }
+ if (e < emin)
+ emin = e;
+ if (e > emax)
+ emax = e;
+ }
+ if (emin > emax)
+ emin = emax; /* case where all values are singular */
+ /* Consistency test in a reduced exponent range. Doing it
+ for the first 10 samples and for prec == p1 (which has
+ some special cases) should be sufficient. */
+ if (ctrt <= 10 || prec == p1)
+ {
+ mpfr_set_emin (emin);
+ mpfr_set_emax (emax);
#ifdef DEBUG_TGENERIC
- /* Useful information in case of assertion failure. */
- printf ("tgeneric: reduced exponent range [%"
- MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d]\n",
- (mpfr_eexp_t) emin, (mpfr_eexp_t) emax);
+ /* Useful information in case of assertion failure. */
+ printf ("tgeneric: reduced exponent range [%"
+ MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d]\n",
+ (mpfr_eexp_t) emin, (mpfr_eexp_t) emax);
#endif
- mpfr_clear_flags ();
+ mpfr_clear_flags ();
#if defined(TWO_ARGS)
- inexact = TEST_FUNCTION (w, x, u, rnd);
+ inexact = TEST_FUNCTION (w, x, u, rnd);
#elif defined(DOUBLE_ARG1)
- inexact = TEST_FUNCTION (w, d, x, rnd);
+ inexact = TEST_FUNCTION (w, d, x, rnd);
#elif defined(DOUBLE_ARG2)
- inexact = TEST_FUNCTION (w, x, d, rnd);
+ inexact = TEST_FUNCTION (w, x, d, rnd);
#elif defined(ULONG_ARG1)
- inexact = TEST_FUNCTION (w, i, x, rnd);
+ inexact = TEST_FUNCTION (w, i, x, rnd);
#elif defined(ULONG_ARG2)
- inexact = TEST_FUNCTION (w, x, i, rnd);
+ inexact = TEST_FUNCTION (w, x, i, rnd);
#else
- inexact = TEST_FUNCTION (w, x, rnd);
-#endif
- flags = __gmpfr_flags;
- mpfr_set_emin (oemin);
- mpfr_set_emax (oemax);
- if (! (SAME_VAL (w, y) &&
- SAME_SIGN (inexact, compare) &&
- flags == oldflags))
- {
- printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
- ", reduced exponent range [%"
- MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d] on:\n",
- (mpfr_eexp_t) emin, (mpfr_eexp_t) emax);
- printf ("x = ");
- mpfr_dump (x);
+ inexact = TEST_FUNCTION (w, x, rnd);
+#endif
+ flags = __gmpfr_flags;
+ mpfr_set_emin (oemin);
+ mpfr_set_emax (oemax);
+ if (! (SAME_VAL (w, y) &&
+ SAME_SIGN (inexact, compare) &&
+ flags == oldflags))
+ {
+ printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
+ ", reduced exponent range [%"
+ MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d] on:\n",
+ (mpfr_eexp_t) emin, (mpfr_eexp_t) emax);
+ printf ("x = ");
+ mpfr_dump (x);
#if defined(TWO_ARGS_ALL)
- printf ("u = ");
- mpfr_dump (u);
-#endif
- printf ("yprec = %u, rnd_mode = %s\n",
- (unsigned int) yprec, mpfr_print_rnd_mode (rnd));
- printf ("Expected:\n y = ");
- mpfr_dump (y);
- printf (" inex = %d, flags =", compare);
- flags_out (oldflags);
- printf ("Got:\n w = ");
- mpfr_dump (w);
- printf (" inex = %d, flags =", inexact);
- flags_out (flags);
- exit (1);
- }
- }
+ printf ("u = ");
+ mpfr_dump (u);
+#endif
+ printf ("yprec = %u, rnd_mode = %s\n",
+ (unsigned int) yprec, mpfr_print_rnd_mode (rnd));
+ printf ("Expected:\n y = ");
+ mpfr_dump (y);
+ printf (" inex = %d, flags =", compare);
+ flags_out (oldflags);
+ printf ("Got:\n w = ");
+ mpfr_dump (w);
+ printf (" inex = %d, flags =", inexact);
+ flags_out (flags);
+ exit (1);
+ }
+ }
+ __gmpfr_flags = oldflags; /* restore the flags */
+ }
+
if (MPFR_IS_SINGULAR (y))
{
if (MPFR_IS_NAN (y) || mpfr_nanflag_p ())