From 199a387dc919cfb667f61dcb539a69d7a4a68232 Mon Sep 17 00:00:00 2001 From: Paul Zimmermann Date: Tue, 11 Feb 2020 16:40:41 +0100 Subject: added -check option --- tests/mpcheck-double.c | 6 +++++ tests/mpcheck-float.c | 6 +++++ tests/mpcheck-float128.c | 6 +++++ tests/mpcheck-longdouble.c | 6 +++++ tests/mpcheck-template1.c | 55 ++++++++++++++++++++++++++++++++++++++++++++-- tests/mpcheck-template2.c | 44 +++++++++++++++++++++++++++++++++++++ tests/mpcheck-template3.c | 51 ++++++++++++++++++++++++++++++++++++++++++ 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); -- cgit v1.2.1