summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/mpfr-test.h2
-rw-r--r--tests/tacos.c1
-rw-r--r--tests/tacosh.c2
-rw-r--r--tests/tasin.c1
-rw-r--r--tests/tasinh.c2
-rw-r--r--tests/tatan.c1
-rw-r--r--tests/tatanh.c2
-rw-r--r--tests/tcos.c1
-rw-r--r--tests/tcosh.c1
-rw-r--r--tests/tests.c121
-rw-r--r--tests/texp.c1
-rw-r--r--tests/texpm1.c2
-rw-r--r--tests/tlog.c1
-rw-r--r--tests/tlog1p.c2
-rw-r--r--tests/tsin.c1
-rw-r--r--tests/tsinh.c2
-rw-r--r--tests/ttan.c1
-rw-r--r--tests/ttanh.c2
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;