diff options
Diffstat (limited to 'tests/tpow_all.c')
-rw-r--r-- | tests/tpow_all.c | 310 |
1 files changed, 176 insertions, 134 deletions
diff --git a/tests/tpow_all.c b/tests/tpow_all.c index ddd59de28..27890eb3d 100644 --- a/tests/tpow_all.c +++ b/tests/tpow_all.c @@ -26,10 +26,21 @@ MA 02110-1301, USA. */ expected result, in particular because such special cases are handled in different ways in each function. */ +/* Execute with at least an argument to report all the errors found by + comparisons. */ + +#include <stdio.h> #include <stdlib.h> #include "mpfr-test.h" +/* Behavior of cmpres (called by test_others): + * 0: stop as soon as an error is found. + * 1: report all errors found by test_others. + * -1: the 1 is changed to this value as soon as an error has been found. + */ +static int all_cmpres_errors; + static char *val[] = { "@NaN@", "-@Inf@", "-4", "-3", "-2", "-1.5", "-1", "-0.5", "-0", "0", "0.5", "1", "1.5", "2", "3", "4", "@Inf@" }; @@ -47,8 +58,9 @@ err (const char *s, int i, int j, int rnd, mpfr_srcptr z, int inex) } static void -cmpres (int i, int j, int rnd, mpfr_srcptr z1, int inex1, - mpfr_srcptr z2, int inex2, const char *s) +cmpres (const char *sx, const char *sy, mp_rnd_t rnd, + mpfr_srcptr z1, int inex1, mpfr_srcptr z2, int inex2, + const char *s) { if (MPFR_IS_NAN (z1) && MPFR_IS_NAN (z2)) return; @@ -56,15 +68,17 @@ cmpres (int i, int j, int rnd, mpfr_srcptr z1, int inex1, return; printf ("Error with %s\n", s); - printf ("x = %s, y = %s, %s\n", val[i], val[j], - mpfr_print_rnd_mode ((mp_rnd_t) rnd)); + printf ("x = %s, y = %s, %s\n", sx, sy, mpfr_print_rnd_mode (rnd)); printf ("Expected "); mpfr_out_str (stdout, 10, 0, z1, GMP_RNDN); printf (", inex = %d\n", SIGN (inex1)); printf ("Got "); mpfr_out_str (stdout, 10, 0, z2, GMP_RNDN); printf (", inex = %d\n", SIGN (inex2)); - exit (1); + if (all_cmpres_errors != 0) + all_cmpres_errors = -1; + else + exit (1); } static int @@ -74,21 +88,127 @@ is_odd (mpfr_srcptr x) return mpfr_integer_p (x) && (mpfr_get_si (x, GMP_RNDN) & 1); } +/* Compare the result (z1,inex1) of mpfr_pow with all flags cleared + with those of mpfr_pow with all flags set and of the other power + functions. Arguments x and y are the input values; sx and sy are + their string representations; rnd contains the rounding mode. */ +static void +test_others (const char *sx, const char *sy, mp_rnd_t rnd, + mpfr_srcptr x, mpfr_srcptr y, mpfr_srcptr z1, int inex1) +{ + mpfr_t z2; + int inex2; + + mpfr_init2 (z2, mpfr_get_prec (z1)); + + __gmpfr_flags = MPFR_FLAGS_ALL; + inex2 = mpfr_pow (z2, x, y, rnd); + cmpres (sx, sy, rnd, z1, inex1, z2, inex2, "mpfr_pow, flags set"); + + /* If y is an integer that fits in an unsigned long and is not -0, + we can test mpfr_pow_ui. */ + if (MPFR_IS_POS (y) && mpfr_integer_p (y) && + mpfr_fits_ulong_p (y, GMP_RNDN)) + { + unsigned long yy = mpfr_get_ui (y, GMP_RNDN); + + mpfr_clear_flags (); + inex2 = mpfr_pow_ui (z2, x, yy, rnd); + cmpres (sx, sy, rnd, z1, inex1, z2, inex2, + "mpfr_pow_ui, flags cleared"); + __gmpfr_flags = MPFR_FLAGS_ALL; + inex2 = mpfr_pow_ui (z2, x, yy, rnd); + cmpres (sx, sy, rnd, z1, inex1, z2, inex2, + "mpfr_pow_ui, flags set"); + + /* If x is an integer that fits in an unsigned long and is not -0, + we can also test mpfr_ui_pow_ui. */ + if (MPFR_IS_POS (x) && mpfr_integer_p (x) && + mpfr_fits_ulong_p (x, GMP_RNDN)) + { + unsigned long xx = mpfr_get_ui (x, GMP_RNDN); + + mpfr_clear_flags (); + inex2 = mpfr_ui_pow_ui (z2, xx, yy, rnd); + cmpres (sx, sy, rnd, z1, inex1, z2, inex2, + "mpfr_ui_pow_ui, flags cleared"); + __gmpfr_flags = MPFR_FLAGS_ALL; + inex2 = mpfr_ui_pow_ui (z2, xx, yy, rnd); + cmpres (sx, sy, rnd, z1, inex1, z2, inex2, + "mpfr_ui_pow_ui, flags set"); + } + } + + /* If y is an integer but not -0, we can test mpfr_pow_z, and + possibly mpfr_pow_si. */ + if ((MPFR_IS_POS (y) || MPFR_NOTZERO (y)) && mpfr_integer_p (y)) + { + mpz_t yyy; + + /* If y fits in a long, we can test mpfr_pow_si. */ + if (mpfr_fits_slong_p (y, GMP_RNDN)) + { + long yy = mpfr_get_si (y, GMP_RNDN); + + mpfr_clear_flags (); + inex2 = mpfr_pow_si (z2, x, yy, rnd); + cmpres (sx, sy, rnd, z1, inex1, z2, inex2, + "mpfr_pow_si, flags cleared"); + __gmpfr_flags = MPFR_FLAGS_ALL; + inex2 = mpfr_pow_si (z2, x, yy, rnd); + cmpres (sx, sy, rnd, z1, inex1, z2, inex2, + "mpfr_pow_si, flags set"); + } + + /* Test mpfr_pow_z. */ + mpz_init (yyy); + mpfr_get_z (yyy, y, GMP_RNDN); + mpfr_clear_flags (); + inex2 = mpfr_pow_z (z2, x, yyy, rnd); + cmpres (sx, sy, rnd, z1, inex1, z2, inex2, + "mpfr_pow_z, flags cleared"); + __gmpfr_flags = MPFR_FLAGS_ALL; + inex2 = mpfr_pow_z (z2, x, yyy, rnd); + cmpres (sx, sy, rnd, z1, inex1, z2, inex2, + "mpfr_pow_z, flags set"); + mpz_clear (yyy); + } + + /* If x is an integer that fits in an unsigned long and is not -0, + we can test mpfr_ui_pow. */ + if (MPFR_IS_POS (x) && mpfr_integer_p (x) && + mpfr_fits_ulong_p (x, GMP_RNDN)) + { + unsigned long xx = mpfr_get_ui (x, GMP_RNDN); + + mpfr_clear_flags (); + inex2 = mpfr_ui_pow (z2, xx, y, rnd); + cmpres (sx, sy, rnd, z1, inex1, z2, inex2, + "mpfr_ui_pow, flags cleared"); + __gmpfr_flags = MPFR_FLAGS_ALL; + inex2 = mpfr_ui_pow (z2, xx, y, rnd); + cmpres (sx, sy, rnd, z1, inex1, z2, inex2, + "mpfr_ui_pow, flags set"); + } + + mpfr_clear (z2); +} + static void tst (void) { int sv = sizeof (val) / sizeof (*val); int i, j; int rnd; - mpfr_t x, y, z1, z2; + mpfr_t x, y, z, tmp; - mpfr_inits2 (53, x, y, z1, z2, (mpfr_ptr) 0); + mpfr_inits2 (53, x, y, z, tmp, (mpfr_ptr) 0); for (i = 0; i < sv; i++) for (j = 0; j < sv; j++) RND_LOOP (rnd) { - int exact, inex1, inex2; + int exact, inex; if (mpfr_set_str (x, val[i], 10, GMP_RNDN) || mpfr_set_str (y, val[j], 10, GMP_RNDN)) @@ -97,167 +217,89 @@ tst (void) exit (1); } mpfr_clear_flags (); - inex1 = mpfr_pow (z1, x, y, (mp_rnd_t) rnd); + inex = mpfr_pow (z, x, y, (mp_rnd_t) rnd); if (mpfr_underflow_p ()) - err ("got underflow", i, j, rnd, z1, inex1); + err ("got underflow", i, j, rnd, z, inex); if (mpfr_overflow_p ()) - err ("got overflow", i, j, rnd, z1, inex1); - if (! MPFR_IS_NAN (z1) && mpfr_nanflag_p ()) - err ("got NaN flag without NaN value", i, j, rnd, z1, inex1); - if (MPFR_IS_NAN (z1) && ! mpfr_nanflag_p ()) - err ("got NaN value without NaN flag", i, j, rnd, z1, inex1); - if (inex1 != 0 && ! mpfr_inexflag_p ()) + err ("got overflow", i, j, rnd, z, inex); + if (! MPFR_IS_NAN (z) && mpfr_nanflag_p ()) + err ("got NaN flag without NaN value", i, j, rnd, z, inex); + if (MPFR_IS_NAN (z) && ! mpfr_nanflag_p ()) + err ("got NaN value without NaN flag", i, j, rnd, z, inex); + if (inex != 0 && ! mpfr_inexflag_p ()) err ("got non-zero ternary value without inexact flag", - i, j, rnd, z1, inex1); - if (inex1 == 0 && mpfr_inexflag_p ()) + i, j, rnd, z, inex); + if (inex == 0 && mpfr_inexflag_p ()) err ("got null ternary value with inexact flag", - i, j, rnd, z1, inex1); - exact = MPFR_IS_SINGULAR (z1) || - (mpfr_mul_2ui (z2, z1, 16, GMP_RNDN), mpfr_integer_p (z2)); - if (exact && inex1 != 0) + i, j, rnd, z, inex); + exact = MPFR_IS_SINGULAR (z) || + (mpfr_mul_2ui (tmp, z, 16, GMP_RNDN), mpfr_integer_p (tmp)); + if (exact && inex != 0) err ("got exact value with ternary flag different from 0", - i, j, rnd, z1, inex1); - if (! exact && inex1 == 0) + i, j, rnd, z, inex); + if (! exact && inex == 0) err ("got inexact value with ternary flag equal to 0", - i, j, rnd, z1, inex1); + i, j, rnd, z, inex); if (MPFR_IS_ZERO (x) && ! MPFR_IS_NAN (y) && MPFR_NOTZERO (y)) { - if (MPFR_IS_NEG (y) && ! MPFR_IS_INF (z1)) - err ("expected an infinity", i, j, rnd, z1, inex1); - if (MPFR_IS_POS (y) && ! MPFR_IS_ZERO (z1)) - err ("expected a zero", i, j, rnd, z1, inex1); - if ((MPFR_IS_NEG (x) && is_odd (y)) ^ MPFR_IS_NEG (z1)) - err ("wrong sign", i, j, rnd, z1, inex1); + if (MPFR_IS_NEG (y) && ! MPFR_IS_INF (z)) + err ("expected an infinity", i, j, rnd, z, inex); + if (MPFR_IS_POS (y) && ! MPFR_IS_ZERO (z)) + err ("expected a zero", i, j, rnd, z, inex); + if ((MPFR_IS_NEG (x) && is_odd (y)) ^ MPFR_IS_NEG (z)) + err ("wrong sign", i, j, rnd, z, inex); } if (! MPFR_IS_NAN (x) && mpfr_cmp_si (x, -1) == 0) { /* x = -1 */ if (! (MPFR_IS_INF (y) || mpfr_integer_p (y)) && - ! MPFR_IS_NAN (z1)) - err ("expected NaN", i, j, rnd, z1, inex1); + ! MPFR_IS_NAN (z)) + err ("expected NaN", i, j, rnd, z, inex); if ((MPFR_IS_INF (y) || (mpfr_integer_p (y) && ! is_odd (y))) - && ! mpfr_equal_p (z1, __gmpfr_one)) - err ("expected 1", i, j, rnd, z1, inex1); + && ! mpfr_equal_p (z, __gmpfr_one)) + err ("expected 1", i, j, rnd, z, inex); if (is_odd (y) && - (MPFR_IS_NAN (z1) || mpfr_cmp_si (z1, -1) != 0)) - err ("expected -1", i, j, rnd, z1, inex1); + (MPFR_IS_NAN (z) || mpfr_cmp_si (z, -1) != 0)) + err ("expected -1", i, j, rnd, z, inex); } if ((mpfr_equal_p (x, __gmpfr_one) || MPFR_IS_ZERO (y)) && - ! mpfr_equal_p (z1, __gmpfr_one)) - err ("expected 1", i, j, rnd, z1, inex1); + ! mpfr_equal_p (z, __gmpfr_one)) + err ("expected 1", i, j, rnd, z, inex); if (MPFR_IS_PURE_FP (x) && MPFR_IS_NEG (x) && MPFR_IS_FP (y) && ! mpfr_integer_p (y) && - ! MPFR_IS_NAN (z1)) - err ("expected NaN", i, j, rnd, z1, inex1); + ! MPFR_IS_NAN (z)) + err ("expected NaN", i, j, rnd, z, inex); if (MPFR_IS_INF (y) && MPFR_NOTZERO (x)) { int cmpabs1 = mpfr_cmpabs (x, __gmpfr_one); if ((MPFR_IS_NEG (y) ? (cmpabs1 < 0) : (cmpabs1 > 0)) && - ! (MPFR_IS_POS (z1) && MPFR_IS_INF (z1))) - err ("expected +Inf", i, j, rnd, z1, inex1); + ! (MPFR_IS_POS (z) && MPFR_IS_INF (z))) + err ("expected +Inf", i, j, rnd, z, inex); if ((MPFR_IS_NEG (y) ? (cmpabs1 > 0) : (cmpabs1 < 0)) && - ! (MPFR_IS_POS (z1) && MPFR_IS_ZERO (z1))) - err ("expected +0", i, j, rnd, z1, inex1); + ! (MPFR_IS_POS (z) && MPFR_IS_ZERO (z))) + err ("expected +0", i, j, rnd, z, inex); } if (MPFR_IS_INF (x) && ! MPFR_IS_NAN (y) && MPFR_NOTZERO (y)) { - if (MPFR_IS_POS (y) && ! MPFR_IS_INF (z1)) - err ("expected an infinity", i, j, rnd, z1, inex1); - if (MPFR_IS_NEG (y) && ! MPFR_IS_ZERO (z1)) - err ("expected a zero", i, j, rnd, z1, inex1); - if ((MPFR_IS_NEG (x) && is_odd (y)) ^ MPFR_IS_NEG (z1)) - err ("wrong sign", i, j, rnd, z1, inex1); - } - - __gmpfr_flags = MPFR_FLAGS_ALL; - inex2 = mpfr_pow (z2, x, y, (mp_rnd_t) rnd); - cmpres (i, j, rnd, z1, inex1, z2, inex2, "mpfr_pow, flags set"); - - if (mpfr_integer_p (y)) - { - long yy = mpfr_get_si (y, GMP_RNDN); - - /* If y >= 0 and y is not -0, we can test mpfr_pow_ui. */ - if (MPFR_IS_POS (y)) - { - MPFR_ASSERTN (yy >= 0); - mpfr_clear_flags (); - inex2 = mpfr_pow_ui (z2, x, yy, (mp_rnd_t) rnd); - cmpres (i, j, rnd, z1, inex1, z2, inex2, - "mpfr_pow_ui, flags cleared"); - __gmpfr_flags = MPFR_FLAGS_ALL; - inex2 = mpfr_pow_ui (z2, x, yy, (mp_rnd_t) rnd); - cmpres (i, j, rnd, z1, inex1, z2, inex2, - "mpfr_pow_ui, flags set"); - - /* If x >= 0 and x is not -0, we can test mpfr_ui_pow_ui. */ - if (mpfr_integer_p (x) && MPFR_IS_POS (x)) - { - unsigned long xx = mpfr_get_ui (x, GMP_RNDN); - - mpfr_clear_flags (); - inex2 = mpfr_ui_pow_ui (z2, xx, yy, (mp_rnd_t) rnd); - cmpres (i, j, rnd, z1, inex1, z2, inex2, - "mpfr_ui_pow_ui, flags cleared"); - __gmpfr_flags = MPFR_FLAGS_ALL; - inex2 = mpfr_ui_pow_ui (z2, xx, yy, (mp_rnd_t) rnd); - cmpres (i, j, rnd, z1, inex1, z2, inex2, - "mpfr_ui_pow_ui, flags set"); - } - } - - /* We can test mpfr_pow_si and mpfr_pow_z when y is not -0. */ - if (MPFR_IS_POS (y) || MPFR_NOTZERO (y)) - { - mpz_t yyy; - - mpfr_clear_flags (); - inex2 = mpfr_pow_si (z2, x, yy, (mp_rnd_t) rnd); - cmpres (i, j, rnd, z1, inex1, z2, inex2, - "mpfr_pow_si, flags cleared"); - __gmpfr_flags = MPFR_FLAGS_ALL; - inex2 = mpfr_pow_si (z2, x, yy, (mp_rnd_t) rnd); - cmpres (i, j, rnd, z1, inex1, z2, inex2, - "mpfr_pow_si, flags set"); - - mpz_init (yyy); - mpfr_get_z (yyy, y, GMP_RNDN); - mpfr_clear_flags (); - inex2 = mpfr_pow_z (z2, x, yyy, (mp_rnd_t) rnd); - cmpres (i, j, rnd, z1, inex1, z2, inex2, - "mpfr_pow_z, flags cleared"); - __gmpfr_flags = MPFR_FLAGS_ALL; - inex2 = mpfr_pow_z (z2, x, yyy, (mp_rnd_t) rnd); - cmpres (i, j, rnd, z1, inex1, z2, inex2, - "mpfr_pow_z, flags set"); - mpz_clear (yyy); - } - } - - /* If x >= 0 and x is not -0, we can test mpfr_ui_pow. */ - if (mpfr_integer_p (x) && MPFR_IS_POS (x)) - { - unsigned long xx = mpfr_get_ui (x, GMP_RNDN); - - mpfr_clear_flags (); - inex2 = mpfr_ui_pow (z2, xx, y, (mp_rnd_t) rnd); - cmpres (i, j, rnd, z1, inex1, z2, inex2, - "mpfr_ui_pow, flags cleared"); - __gmpfr_flags = MPFR_FLAGS_ALL; - inex2 = mpfr_ui_pow (z2, xx, y, (mp_rnd_t) rnd); - cmpres (i, j, rnd, z1, inex1, z2, inex2, - "mpfr_ui_pow, flags set"); + if (MPFR_IS_POS (y) && ! MPFR_IS_INF (z)) + err ("expected an infinity", i, j, rnd, z, inex); + if (MPFR_IS_NEG (y) && ! MPFR_IS_ZERO (z)) + err ("expected a zero", i, j, rnd, z, inex); + if ((MPFR_IS_NEG (x) && is_odd (y)) ^ MPFR_IS_NEG (z)) + err ("wrong sign", i, j, rnd, z, inex); } + test_others (val[i], val[j], (mp_rnd_t) rnd, x, y, z, inex); } - mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0); + mpfr_clears (x, y, z, tmp, (mpfr_ptr) 0); } int -main (void) +main (int argc, char *argv[]) { tests_start_mpfr (); + all_cmpres_errors = argc > 1; tst (); tests_end_mpfr (); - return 0; + return all_cmpres_errors < 0; } |