summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Zimmermann <Paul.Zimmermann@inria.fr>2020-02-11 16:40:41 +0100
committerPaul Zimmermann <Paul.Zimmermann@inria.fr>2020-02-11 16:40:41 +0100
commit199a387dc919cfb667f61dcb539a69d7a4a68232 (patch)
tree17baa1f6daf6fb9946808251759825a64b408cb9
parentac2fc471a49d37cc00e4298cea276d8351fd5a8b (diff)
downloadmpc-git-199a387dc919cfb667f61dcb539a69d7a4a68232.tar.gz
added -check option
-rw-r--r--tests/mpcheck-double.c6
-rw-r--r--tests/mpcheck-float.c6
-rw-r--r--tests/mpcheck-float128.c6
-rw-r--r--tests/mpcheck-longdouble.c6
-rw-r--r--tests/mpcheck-template1.c55
-rw-r--r--tests/mpcheck-template2.c44
-rw-r--r--tests/mpcheck-template3.c51
7 files changed, 172 insertions, 2 deletions
diff --git a/tests/mpcheck-double.c b/tests/mpcheck-double.c
index 0b4fd4d..ba85952 100644
--- a/tests/mpcheck-double.c
+++ b/tests/mpcheck-double.c
@@ -172,6 +172,12 @@ main (int argc, char *argv[])
argc --;
argv ++;
}
+ else if (strcmp (argv[1], "-check") == 0)
+ {
+ recheck = 1;
+ argc --;
+ argv ++;
+ }
else
{
fprintf (stderr, "Unknown option %s\n", argv[1]);
diff --git a/tests/mpcheck-float.c b/tests/mpcheck-float.c
index 590d261..fe3cf77 100644
--- a/tests/mpcheck-float.c
+++ b/tests/mpcheck-float.c
@@ -177,6 +177,12 @@ main (int argc, char *argv[])
argc --;
argv ++;
}
+ else if (strcmp (argv[1], "-check") == 0)
+ {
+ recheck = 1;
+ argc --;
+ argv ++;
+ }
else
{
fprintf (stderr, "Unknown option %s\n", argv[1]);
diff --git a/tests/mpcheck-float128.c b/tests/mpcheck-float128.c
index 38b88d8..7b8f495 100644
--- a/tests/mpcheck-float128.c
+++ b/tests/mpcheck-float128.c
@@ -182,6 +182,12 @@ main (int argc, char *argv[])
argc --;
argv ++;
}
+ else if (strcmp (argv[1], "-check") == 0)
+ {
+ recheck = 1;
+ argc --;
+ argv ++;
+ }
else
{
fprintf (stderr, "Unknown option %s\n", argv[1]);
diff --git a/tests/mpcheck-longdouble.c b/tests/mpcheck-longdouble.c
index d81b983..3dc1688 100644
--- a/tests/mpcheck-longdouble.c
+++ b/tests/mpcheck-longdouble.c
@@ -165,6 +165,12 @@ main (int argc, char *argv[])
argc --;
argv ++;
}
+ else if (strcmp (argv[1], "-check") == 0)
+ {
+ recheck = 1;
+ argc --;
+ argv ++;
+ }
else
{
fprintf (stderr, "Unknown option %s\n", argv[1]);
diff --git a/tests/mpcheck-template1.c b/tests/mpcheck-template1.c
index 3f05921..ee56e01 100644
--- a/tests/mpcheck-template1.c
+++ b/tests/mpcheck-template1.c
@@ -24,17 +24,65 @@ along with this program. If not, see http://www.gnu.org/licenses/ .
#define TOSTRING(x) STRINGIFY(x)
#define FUN CAT2(test_,FOO)
+#define CHECK CAT2(check_,FOO)
#define MPC_FOO CAT2(mpc_,FOO)
#define CFOO CAT2(CAT2(c,FOO),SUFFIX)
#define BAR TOSTRING(FOO)
+#define EXTRA 20
+
+/* routine to double-check result from MPC with more precision and without
+ reduced exponent range */
+static void
+CHECK (mpc_t x, mpc_t z)
+{
+ mpfr_exp_t saved_emin = mpfr_get_emin ();
+ mpfr_exp_t saved_emax = mpfr_get_emax ();
+ mpfr_prec_t p = mpfr_get_prec (mpc_realref (x)), pp = p + EXTRA;
+ mpc_t t;
+ int ok, inex_re, inex_im;
+
+ /* enlarge exponent range to the largest possible */
+ mpfr_set_emin (mpfr_get_emin_min ());
+ mpfr_set_emax (mpfr_get_emax_max ());
+
+ mpc_init2 (t, pp);
+ MPC_FOO (t, x, MPC_RNDNN);
+ inex_re = mpfr_prec_round (mpc_realref (t), p, MPFR_RNDN);
+ inex_im = mpfr_prec_round (mpc_imagref (t), p, MPFR_RNDN);
+ /* restore exponent range */
+ mpfr_set_emin (saved_emin);
+ mpfr_set_emax (saved_emax);
+ inex_re = mpfr_check_range (mpc_realref (t), inex_re, MPFR_RNDN);
+ inex_re = mpfr_subnormalize (mpc_realref (t), inex_re, MPFR_RNDN);
+ inex_im = mpfr_check_range (mpc_imagref (t), inex_im, MPFR_RNDN);
+ inex_im = mpfr_subnormalize (mpc_imagref (t), inex_im, MPFR_RNDN);
+
+ /* check real parts agree */
+ ok = mpfr_agree (mpc_realref (z), mpc_realref (t), inex_re)
+ && mpfr_agree (mpc_imagref (z), mpc_imagref (t), inex_im);
+
+ if (!ok)
+ {
+ mpfr_printf ("Potential bug in mpc_%s for x=(%Re,%Re)\n", BAR,
+ mpc_realref (x), mpc_imagref (x));
+ mpfr_printf (" mpc_%s to precision %lu gives (%Re,%Re)\n", BAR, p,
+ mpc_realref (z), mpc_imagref (z));
+ mpfr_printf (" mpc_%s to precision %lu gives (%Re,%Re)\n", BAR, pp,
+ mpc_realref (t), mpc_imagref (t));
+ exit (1);
+ }
+
+ mpc_clear (t);
+}
+
static void
FUN (mpfr_prec_t p, unsigned long n)
{
unsigned long i = 0;
mpc_t x, z, t;
TYPE complex xx, zz;
- int inex;
+ int inex, cmp;
unsigned long errors = 0, max_err_re = 0, max_err_im = 0;
/* allow reduced exponent range */
#if defined(FOO_EMIN) || defined(FOO_EMAX)
@@ -60,7 +108,8 @@ FUN (mpfr_prec_t p, unsigned long n)
xx = mpc_get_type (x, MPC_RNDNN);
zz = CFOO (xx);
mpc_set_type (t, zz, MPFR_RNDN);
- if (mpcheck_mpc_cmp (t, z) != 0)
+ cmp = mpcheck_mpc_cmp (t, z);
+ if (cmp != 0)
{
unsigned long err_re = ulp_error (mpc_realref (t), mpc_realref (z));
unsigned long err_im = ulp_error (mpc_imagref (t), mpc_imagref (z));
@@ -74,6 +123,8 @@ FUN (mpfr_prec_t p, unsigned long n)
mpfr_printf (" c%s gives (%Re,%Re)\n", BAR,
mpc_realref (t), mpc_imagref (t));
}
+ if (recheck)
+ CHECK (x, z);
errors ++;
if (err_re > max_err_re)
{
diff --git a/tests/mpcheck-template2.c b/tests/mpcheck-template2.c
index 3539c2d..7a2a8c0 100644
--- a/tests/mpcheck-template2.c
+++ b/tests/mpcheck-template2.c
@@ -24,10 +24,52 @@ along with this program. If not, see http://www.gnu.org/licenses/ .
#define TOSTRING(x) STRINGIFY(x)
#define FUN CAT2(test_,FOO)
+#define CHECK CAT2(check_,FOO)
#define MPC_FOO CAT2(mpc_,FOO)
#define CFOO CAT2(CAT2(c,FOO),SUFFIX)
#define BAR TOSTRING(FOO)
+#define EXTRA 20
+
+/* routine to double-check result from MPC with more precision and without
+ reduced exponent range */
+static void
+CHECK (mpc_t x, mpfr_t z)
+{
+ mpfr_exp_t saved_emin = mpfr_get_emin ();
+ mpfr_exp_t saved_emax = mpfr_get_emax ();
+ mpfr_prec_t p = mpfr_get_prec (mpc_realref (x)), pp = p + EXTRA;
+ mpfr_t t;
+ int inex, ok;
+
+ /* enlarge exponent range to the largest possible */
+ mpfr_set_emin (mpfr_get_emin_min ());
+ mpfr_set_emax (mpfr_get_emax_max ());
+
+ mpfr_init2 (t, pp);
+ MPC_FOO (t, x, MPFR_RNDN);
+ inex = mpfr_prec_round (t, p, MPFR_RNDN);
+ /* restore exponent range */
+ mpfr_set_emin (saved_emin);
+ mpfr_set_emax (saved_emax);
+ inex = mpfr_check_range (t, inex, MPFR_RNDN);
+ inex = mpfr_subnormalize (t, inex, MPFR_RNDN);
+
+ /* check real parts agree */
+ ok = mpfr_agree (z, t, inex);
+
+ if (!ok)
+ {
+ mpfr_printf ("Potential bug in mpc_%s for x=(%Re,%Re)\n", BAR,
+ mpc_realref (x), mpc_imagref (x));
+ mpfr_printf (" mpc_%s to precision %lu gives %Re\n", BAR, p, z);
+ mpfr_printf (" mpc_%s to precision %lu gives %Re\n", BAR, pp, t);
+ exit (1);
+ }
+
+ mpfr_clear (t);
+}
+
static void
FUN (mpfr_prec_t p, unsigned long n)
{
@@ -66,6 +108,8 @@ FUN (mpfr_prec_t p, unsigned long n)
mpfr_printf (" mpc_%s gives %Re\n", BAR, z);
mpfr_printf (" c%s gives %Re\n", BAR, t);
}
+ if (recheck)
+ CHECK (x, z);
errors++;
if (err > max_err)
{
diff --git a/tests/mpcheck-template3.c b/tests/mpcheck-template3.c
index c16d8de..e6718a8 100644
--- a/tests/mpcheck-template3.c
+++ b/tests/mpcheck-template3.c
@@ -24,12 +24,61 @@ along with this program. If not, see http://www.gnu.org/licenses/ .
#define TOSTRING(x) STRINGIFY(x)
#define FUN CAT2(test_,FOO)
+#define CHECK CAT2(check_,FOO)
#define MPC_FOO CAT2(mpc_,FOO)
#ifndef CFOO
#define CFOO CAT2(CAT2(c,FOO),SUFFIX)
#endif
#define BAR TOSTRING(FOO)
+#define EXTRA 20
+
+/* routine to double-check result from MPC with more precision and without
+ reduced exponent range */
+static void
+CHECK (mpc_t x, mpc_t y, mpc_t z)
+{
+ mpfr_exp_t saved_emin = mpfr_get_emin ();
+ mpfr_exp_t saved_emax = mpfr_get_emax ();
+ mpfr_prec_t p = mpfr_get_prec (mpc_realref (x)), pp = p + EXTRA;
+ mpc_t t;
+ int ok, inex_re, inex_im;
+
+ /* enlarge exponent range to the largest possible */
+ mpfr_set_emin (mpfr_get_emin_min ());
+ mpfr_set_emax (mpfr_get_emax_max ());
+
+ mpc_init2 (t, pp);
+ MPC_FOO (t, x, y, MPC_RNDNN);
+ inex_re = mpfr_prec_round (mpc_realref (t), p, MPFR_RNDN);
+ inex_im = mpfr_prec_round (mpc_imagref (t), p, MPFR_RNDN);
+ /* restore exponent range */
+ mpfr_set_emin (saved_emin);
+ mpfr_set_emax (saved_emax);
+ inex_re = mpfr_check_range (mpc_realref (t), inex_re, MPFR_RNDN);
+ inex_re = mpfr_subnormalize (mpc_realref (t), inex_re, MPFR_RNDN);
+ inex_im = mpfr_check_range (mpc_imagref (t), inex_im, MPFR_RNDN);
+ inex_im = mpfr_subnormalize (mpc_imagref (t), inex_im, MPFR_RNDN);
+
+ /* check real parts agree */
+ ok = mpfr_agree (mpc_realref (z), mpc_realref (t), inex_re)
+ && mpfr_agree (mpc_imagref (z), mpc_imagref (t), inex_im);
+
+ if (!ok)
+ {
+ mpfr_printf ("Potential bug in mpc_%s for\n", BAR);
+ mpfr_printf (" x=(%Re,%Re)\n", mpc_realref (x), mpc_imagref (x));
+ mpfr_printf (" y=(%Re,%Re)\n", mpc_realref (y), mpc_imagref (y));
+ mpfr_printf (" mpc_%s to precision %lu gives (%Re,%Re)\n", BAR, p,
+ mpc_realref (z), mpc_imagref (z));
+ mpfr_printf (" mpc_%s to precision %lu gives (%Re,%Re)\n", BAR, pp,
+ mpc_realref (t), mpc_imagref (t));
+ exit (1);
+ }
+
+ mpc_clear (t);
+}
+
static void
FUN (mpfr_prec_t p, unsigned long n)
{
@@ -108,6 +157,8 @@ FUN (mpfr_prec_t p, unsigned long n)
Max_err_im = max_err_im;
}
}
+ if (recheck && cmp != 0)
+ CHECK (x, y, z);
}
mpc_clear (x);
mpc_clear (y);