diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2015-06-10 10:41:54 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2015-06-10 10:41:54 +0000 |
commit | 47f9890b88d607718fbc20088840e8de602b19fb (patch) | |
tree | 686e9c313290fdfffc3730025ad41d65064ab2ee /tests/tgeneric.c | |
parent | ed7872ddd952612fd083252fabe19063b80b6690 (diff) | |
download | mpfr-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.c | 283 |
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 ()) |