summaryrefslogtreecommitdiff
path: root/tests/mpcheck-template1.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/mpcheck-template1.c')
-rw-r--r--tests/mpcheck-template1.c55
1 files changed, 53 insertions, 2 deletions
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)
{