diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2007-08-31 15:50:48 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2007-08-31 15:50:48 +0000 |
commit | f502f7f43df2ec8ec4d1f41ec1273cae3432f811 (patch) | |
tree | 439721b589663e865a23d888f27d9cebc877500f | |
parent | 50e62851e8bb07533025e43149e8689239f06ae5 (diff) | |
download | mpfr-f502f7f43df2ec8ec4d1f41ec1273cae3432f811.tar.gz |
Added generic bad case tests.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@4817 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r-- | tests/mpfr-test.h | 2 | ||||
-rw-r--r-- | tests/tacos.c | 1 | ||||
-rw-r--r-- | tests/tacosh.c | 2 | ||||
-rw-r--r-- | tests/tasin.c | 1 | ||||
-rw-r--r-- | tests/tasinh.c | 2 | ||||
-rw-r--r-- | tests/tatan.c | 1 | ||||
-rw-r--r-- | tests/tatanh.c | 2 | ||||
-rw-r--r-- | tests/tcos.c | 1 | ||||
-rw-r--r-- | tests/tcosh.c | 1 | ||||
-rw-r--r-- | tests/tests.c | 121 | ||||
-rw-r--r-- | tests/texp.c | 1 | ||||
-rw-r--r-- | tests/texpm1.c | 2 | ||||
-rw-r--r-- | tests/tlog.c | 1 | ||||
-rw-r--r-- | tests/tlog1p.c | 2 | ||||
-rw-r--r-- | tests/tsin.c | 1 | ||||
-rw-r--r-- | tests/tsinh.c | 2 | ||||
-rw-r--r-- | tests/ttan.c | 1 | ||||
-rw-r--r-- | tests/ttanh.c | 2 |
18 files changed, 146 insertions, 0 deletions
diff --git a/tests/mpfr-test.h b/tests/mpfr-test.h index 3c97147af..a799fb475 100644 --- a/tests/mpfr-test.h +++ b/tests/mpfr-test.h @@ -80,6 +80,8 @@ void set_emin _MPFR_PROTO ((mp_exp_t)); void set_emax _MPFR_PROTO ((mp_exp_t)); void tests_default_random _MPFR_PROTO ((mpfr_ptr, int, mp_exp_t, mp_exp_t)); void data_check _MPFR_PROTO ((char *, int (*) (), char *)); +void bad_cases _MPFR_PROTO ((int (*)(), int (*)(), char *, int, mp_exp_t, + mp_exp_t, mp_prec_t, mp_prec_t, mp_prec_t, int)); int mpfr_cmp_str _MPFR_PROTO ((mpfr_srcptr x, const char *, int, mp_rnd_t)); #define mpfr_cmp_str1(x,s) mpfr_cmp_str(x,s,10,GMP_RNDN) diff --git a/tests/tacos.c b/tests/tacos.c index 26a148937..de0581c5d 100644 --- a/tests/tacos.c +++ b/tests/tacos.c @@ -180,6 +180,7 @@ main (void) mpfr_clear (y); data_check ("data/acos", mpfr_acos, "mpfr_acos"); + bad_cases (mpfr_acos, mpfr_cos, "mpfr_acos", 0, -40, 2, 4, 128, 800, 30); tests_end_mpfr (); return 0; diff --git a/tests/tacosh.c b/tests/tacosh.c index 57cb5e338..ecfad4a87 100644 --- a/tests/tacosh.c +++ b/tests/tacosh.c @@ -161,6 +161,8 @@ main (int argc, char *argv[]) test_generic (2, 100, 25); data_check ("data/acosh", mpfr_acosh, "mpfr_acosh"); + bad_cases (mpfr_acosh, mpfr_cosh, "mpfr_acosh", 0, -128, 29, + 4, 128, 800, 40); tests_end_mpfr (); return 0; diff --git a/tests/tasin.c b/tests/tasin.c index 76dda318c..be323499d 100644 --- a/tests/tasin.c +++ b/tests/tasin.c @@ -208,6 +208,7 @@ main (void) tests_end_mpfr (); data_check ("data/asin", mpfr_asin, "mpfr_asin"); + bad_cases (mpfr_asin, mpfr_sin, "mpfr_asin", 256, -40, 1, 4, 128, 800, 30); return 0; } diff --git a/tests/tasinh.c b/tests/tasinh.c index d87c2d17a..2a86c3c01 100644 --- a/tests/tasinh.c +++ b/tests/tasinh.c @@ -153,6 +153,8 @@ main (int argc, char *argv[]) test_generic (2, 100, 25); data_check ("data/asinh", mpfr_asinh, "mpfr_asinh"); + bad_cases (mpfr_asinh, mpfr_sinh, "mpfr_asinh", 256, -128, 29, + 4, 128, 800, 40); tests_end_mpfr (); return 0; diff --git a/tests/tatan.c b/tests/tatan.c index e187f859a..5dd93599c 100644 --- a/tests/tatan.c +++ b/tests/tatan.c @@ -420,6 +420,7 @@ main (int argc, char *argv[]) test_generic_atan2_neg (2, 200, 17); data_check ("data/atan", mpfr_atan, "mpfr_atan"); + bad_cases (mpfr_atan, mpfr_tan, "mpfr_atan", 256, -40, 1, 4, 128, 800, 40); tests_end_mpfr (); return 0; diff --git a/tests/tatanh.c b/tests/tatanh.c index 9e6727039..a237c7af6 100644 --- a/tests/tatanh.c +++ b/tests/tatanh.c @@ -181,6 +181,8 @@ main (int argc, char *argv[]) test_generic (2, 100, 25); data_check ("data/atanh", mpfr_atanh, "mpfr_atanh"); + bad_cases (mpfr_atanh, mpfr_tanh, "mpfr_atanh", 256, -128, 9, + 4, 128, 800, 100); tests_end_mpfr (); return 0; diff --git a/tests/tcos.c b/tests/tcos.c index af153d22a..8d66232ff 100644 --- a/tests/tcos.c +++ b/tests/tcos.c @@ -361,6 +361,7 @@ main (int argc, char *argv[]) mpfr_clear (y); data_check ("data/cos", mpfr_cos, "mpfr_cos"); + bad_cases (mpfr_cos, mpfr_acos, "mpfr_cos", 256, -40, 0, 4, 128, 800, 50); tests_end_mpfr (); return 0; diff --git a/tests/tcosh.c b/tests/tcosh.c index b07507d2c..3ee40daf7 100644 --- a/tests/tcosh.c +++ b/tests/tcosh.c @@ -197,6 +197,7 @@ main (int argc, char *argv[]) test_generic (2, 100, 100); data_check ("data/cosh", mpfr_cosh, "mpfr_cosh"); + bad_cases (mpfr_cosh, mpfr_acosh, "mpfr_cosh", 0, 1, 255, 4, 128, 800, 100); tests_end_mpfr (); return 0; diff --git a/tests/tests.c b/tests/tests.c index c1228f7ea..768e00f2f 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -597,3 +597,124 @@ data_check (char *f, int (*foo) (), char *name) fclose (fp); } + +/* Test n random bad cases. A precision py in [pymin,pymax] and + * a number y of precision py are chosen randomly. One computes + * x = inv(y) in precision px = py + psup (rounded to nearest). + * Then (in general), y is a bad case for fct in precision py (in + * the directed rounding modes, but also in the rounding-to-nearest + * mode for some lower precision: see data_check). + * fct, inv, name: data related to the function. + * pos, emin, emax: arguments for tests_default_random. + */ +void +bad_cases (int (*fct)(), int (*inv)(), char *name, + int pos, mp_exp_t emin, mp_exp_t emax, + mp_prec_t pymin, mp_prec_t pymax, mp_prec_t psup, + int n) +{ + mpfr_t x, y, z; + char *dbgenv; + int i, dbg; + + dbgenv = getenv ("MPFR_DEBUG_BADCASES"); + dbg = dbgenv != 0 ? atoi (dbgenv) : 0; /* debug level */ + mpfr_inits (x, y, z, (void *) 0); + for (i = 0; i < n; i++) + { + mp_prec_t px, py, pz; + int inex; + + if (dbg) + printf ("bad_cases: i = %d\n", i); + py = pymin + (randlimb () % (pymax - pymin + 1)); + mpfr_set_prec (y, py); + tests_default_random (y, pos, emin, emax); + if (dbg) + { + printf ("bad_cases: yprec =%4ld, y = ", (long) py); + mpfr_out_str (stdout, 16, 0, y, GMP_RNDN); + printf ("\n"); + } + px = py + psup; + mpfr_set_prec (x, px); + mpfr_clear_flags (); + inv (x, y, GMP_RNDN); + if (mpfr_nanflag_p () || mpfr_overflow_p () || mpfr_underflow_p ()) + { + if (dbg) + printf ("bad_cases: no normal inverse\n"); + goto next_i; + } + if (dbg > 1) + { + printf ("bad_cases: x = "); + mpfr_out_str (stdout, 16, 0, x, GMP_RNDN); + printf ("\n"); + } + pz = px; + do + { + pz += 32; + mpfr_set_prec (z, pz); + if (fct (z, x, GMP_RNDN) == 0) + { + if (dbg) + printf ("bad_cases: exact case\n"); + goto next_i; + } + if (dbg) + { + if (dbg > 1) + { + printf ("bad_cases: %s(x) ~= ", name); + mpfr_out_str (stdout, 16, 0, z, GMP_RNDN); + } + else + { + printf ("bad_cases: [GMP_RNDZ] ~= "); + mpfr_out_str (stdout, 16, 40, z, GMP_RNDZ); + } + printf ("\n"); + } + inex = mpfr_prec_round (z, py, GMP_RNDN); + if (mpfr_nanflag_p () || mpfr_overflow_p () || mpfr_underflow_p () + || ! mpfr_equal_p (z, y)) + { + if (dbg) + printf ("bad_cases: inverse doesn't match\n"); + goto next_i; + } + } + while (inex == 0); + /* We really have a bad case. */ + do + py--; + while (py >= MPFR_PREC_MIN && mpfr_prec_round (z, py, GMP_RNDZ) == 0); + py++; + /* py is now the smallest output precision such that we have + a bad case in the directed rounding modes. */ + if (mpfr_prec_round (y, py, GMP_RNDZ) != 0) + { + printf ("Internal error for i = %d\n", i); + exit (1); + } + if ((inex > 0 && MPFR_IS_POS (z)) || + (inex < 0 && MPFR_IS_NEG (z))) + { + mpfr_nexttozero (y); + if (mpfr_zero_p (y)) + goto next_i; + } + if (dbg) + { + printf ("bad_cases: yprec =%4ld, y = ", (long) py); + mpfr_out_str (stdout, 16, 0, y, GMP_RNDN); + printf ("\n"); + } + /* Note: y is now the expected result rounded towards zero. */ + test4rm (fct, x, y, z, GMP_RNDZ, 0, name); + next_i: ; + } + mpfr_clears (x, y, z, (void *) 0); +} diff --git a/tests/texp.c b/tests/texp.c index 964a1fe07..49286fbf9 100644 --- a/tests/texp.c +++ b/tests/texp.c @@ -645,6 +645,7 @@ main (int argc, char *argv[]) overflowed_exp0 (); data_check ("data/exp", mpfr_exp, "mpfr_exp"); + bad_cases (mpfr_exp, mpfr_log, "mpfr_exp", 0, -256, 255, 4, 128, 800, 50); tests_end_mpfr (); return 0; diff --git a/tests/texpm1.c b/tests/texpm1.c index d35138bdf..cd947cabb 100644 --- a/tests/texpm1.c +++ b/tests/texpm1.c @@ -165,6 +165,8 @@ main (int argc, char *argv[]) test_generic (2, 100, 100); data_check ("data/expm1", mpfr_expm1, "mpfr_expm1"); + bad_cases (mpfr_expm1, mpfr_log1p, "mpfr_expm1", 256, -256, 255, + 4, 128, 800, 40); tests_end_mpfr (); return 0; diff --git a/tests/tlog.c b/tests/tlog.c index cc6afb2c4..0f96d2f21 100644 --- a/tests/tlog.c +++ b/tests/tlog.c @@ -353,6 +353,7 @@ main (int argc, char *argv[]) test_generic (2, 100, 40); data_check ("data/log", mpfr_log, "mpfr_log"); + bad_cases (mpfr_log, mpfr_exp, "mpfr_log", 256, -30, 30, 4, 128, 800, 50); done: tests_end_mpfr (); diff --git a/tests/tlog1p.c b/tests/tlog1p.c index 3db979844..8bce9aa1f 100644 --- a/tests/tlog1p.c +++ b/tests/tlog1p.c @@ -128,6 +128,8 @@ main (int argc, char *argv[]) test_generic (2, 100, 50); data_check ("data/log1p", mpfr_log1p, "mpfr_log1p"); + bad_cases (mpfr_log1p, mpfr_expm1, "mpfr_log1p", 256, -64, 40, + 4, 128, 800, 40); tests_end_mpfr (); return 0; diff --git a/tests/tsin.c b/tests/tsin.c index 633d97e90..7d9870f4d 100644 --- a/tests/tsin.c +++ b/tests/tsin.c @@ -361,6 +361,7 @@ main (int argc, char *argv[]) check_tiny (); data_check ("data/sin", mpfr_sin, "mpfr_sin"); + bad_cases (mpfr_sin, mpfr_asin, "mpfr_sin", 256, -40, 0, 4, 128, 800, 50); tests_end_mpfr (); return 0; diff --git a/tests/tsinh.c b/tests/tsinh.c index 460e1afaf..c9f0615f0 100644 --- a/tests/tsinh.c +++ b/tests/tsinh.c @@ -101,6 +101,8 @@ main (int argc, char *argv[]) test_generic (2, 100, 100); data_check ("data/sinh", mpfr_sinh, "mpfr_sinh"); + bad_cases (mpfr_sinh, mpfr_asinh, "mpfr_sinh", 256, -256, 255, + 4, 128, 800, 100); tests_end_mpfr (); return 0; diff --git a/tests/ttan.c b/tests/ttan.c index 1f7befc42..6ce3aae96 100644 --- a/tests/ttan.c +++ b/tests/ttan.c @@ -156,6 +156,7 @@ main (int argc, char *argv[]) test_generic (2, 100, 10); data_check ("data/tan", mpfr_tan, "mpfr_tan"); + bad_cases (mpfr_tan, mpfr_atan, "mpfr_tan", 256, -256, 255, 4, 128, 800, 40); tests_end_mpfr (); return 0; diff --git a/tests/ttanh.c b/tests/ttanh.c index 5985163ee..a9eb8c658 100644 --- a/tests/ttanh.c +++ b/tests/ttanh.c @@ -130,6 +130,8 @@ main (int argc, char *argv[]) test_generic (2, 100, 100); data_check ("data/tanh", mpfr_tanh, "mpfr_tanh"); + bad_cases (mpfr_tanh, mpfr_atanh, "mpfr_tanh", 256, -128, 0, + 4, 128, 800, 100); tests_end_mpfr (); return 0; |