summaryrefslogtreecommitdiff
path: root/tests/tget_z.c
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2017-10-09 11:39:32 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2017-10-09 11:39:32 +0000
commitd3d5d5363383b3df052201ab53c711519000ab5d (patch)
treeb34e4977b3e8013aafb7c4fc37519d50856dc712 /tests/tget_z.c
parent31259a4fabccd443cb09128969c1cbeda26f54d4 (diff)
downloadmpfr-d3d5d5363383b3df052201ab53c711519000ab5d.tar.gz
[src/get_z.c] Fixed failure in mpfr_get_z when called with a very
reduced exponent range. [tests/tget_z.c] Added tests in the various rounding modes (triggering a failure before the above fix). Also call check_one() on an integer congruent to 1 mod 4 (useful to check even rounding). Fixed 2 issues in the error message (for inex and the flags). git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@11777 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'tests/tget_z.c')
-rw-r--r--tests/tget_z.c155
1 files changed, 104 insertions, 51 deletions
diff --git a/tests/tget_z.c b/tests/tget_z.c
index 756e2674e..b5b368a5f 100644
--- a/tests/tget_z.c
+++ b/tests/tget_z.c
@@ -73,10 +73,10 @@ static void
check_one (mpz_ptr z)
{
mpfr_exp_t emin, emax;
- int inex, ex_inex, same;
+ int inex;
int sh, neg;
mpfr_t f;
- mpz_t got, ex;
+ mpz_t got, ex, t;
emin = mpfr_get_emin ();
emax = mpfr_get_emax ();
@@ -84,72 +84,121 @@ check_one (mpz_ptr z)
mpfr_init2 (f, MAX (mpz_sizeinbase (z, 2), MPFR_PREC_MIN));
mpz_init (got);
mpz_init (ex);
+ mpz_init (t);
for (sh = -2*GMP_NUMB_BITS ; sh < 2*GMP_NUMB_BITS ; sh++)
{
inex = mpfr_set_z (f, z, MPFR_RNDN); /* exact */
MPFR_ASSERTN (inex == 0);
- if (sh < 0)
- {
- mpz_tdiv_q_2exp (ex, z, -sh);
- inex = mpfr_div_2exp (f, f, -sh, MPFR_RNDN);
- }
- else
- {
- mpz_mul_2exp (ex, z, sh);
- inex = mpfr_mul_2exp (f, f, sh, MPFR_RNDN);
- }
+ inex = sh < 0 ?
+ mpfr_div_2exp (f, f, -sh, MPFR_RNDN) :
+ mpfr_mul_2exp (f, f, sh, MPFR_RNDN);
MPFR_ASSERTN (inex == 0);
for (neg = 0; neg <= 1; neg++)
{
- /* Test (-1)^neg * z * 2^sh */
- int fi, e;
- mpfr_flags_t flags[3] = { 0, MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE,
- MPFR_FLAGS_ALL }, ex_flags, gt_flags;
+ int rnd;
- ex_inex = - mpfr_cmp_z (f, ex);
+ /* Test (-1)^neg * z * 2^sh */
- for (fi = 0; fi < numberof (flags); fi++)
- for (e = 0; e < 2; e++)
- {
- if (e)
+ RND_LOOP_NO_RNDF (rnd)
+ {
+ int ex_inex, same;
+ int d, fi, e;
+ mpfr_flags_t flags[3] = { 0, MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE,
+ MPFR_FLAGS_ALL }, ex_flags, gt_flags;
+
+ if (neg)
+ mpz_neg (ex, z);
+ else
+ mpz_set (ex, z);
+
+ if (sh < 0)
+ switch (rnd)
{
- mpfr_exp_t ef;
-
- if (MPFR_IS_ZERO (f))
- break;
- ef = MPFR_GET_EXP (f);
- set_emin (ef);
- set_emax (ef);
+ case MPFR_RNDN:
+ mpz_set_si (t, neg ? -1 : 1);
+ mpz_mul_2exp (t, t, -sh - 1);
+ mpz_add (ex, ex, t);
+ d = mpz_divisible_2exp_p (ex, -sh);
+ mpz_tdiv_q_2exp (ex, ex, -sh);
+ if (d && mpz_tstbit (ex, 0) != 0) /* even rounding */
+ {
+ if (neg)
+ mpz_add_ui (ex, ex, 1);
+ else
+ mpz_sub_ui (ex, ex, 1);
+ }
+ break;
+ case MPFR_RNDZ:
+ mpz_tdiv_q_2exp (ex, ex, -sh);
+ break;
+ case MPFR_RNDU:
+ mpz_cdiv_q_2exp (ex, ex, -sh);
+ break;
+ case MPFR_RNDD:
+ mpz_fdiv_q_2exp (ex, ex, -sh);
+ break;
+ case MPFR_RNDA:
+ if (neg)
+ mpz_fdiv_q_2exp (ex, ex, -sh);
+ else
+ mpz_cdiv_q_2exp (ex, ex, -sh);
+ break;
+ default:
+ MPFR_ASSERTN (0);
}
- ex_flags = __gmpfr_flags = flags[fi];
- if (ex_inex != 0)
- ex_flags |= MPFR_FLAGS_INEXACT;
- inex = mpfr_get_z (got, f, MPFR_RNDZ);
- gt_flags = __gmpfr_flags;
- set_emin (emin);
- set_emax (emax);
- same = SAME_SIGN (inex, ex_inex);
-
- if (mpz_cmp (got, ex) != 0 || !same || gt_flags != ex_flags)
+ else
+ mpz_mul_2exp (ex, ex, sh);
+
+ ex_inex = - mpfr_cmp_z (f, ex);
+ ex_inex = VSIGN (ex_inex);
+
+ for (fi = 0; fi < numberof (flags); fi++)
+ for (e = 0; e < 2; e++)
{
- printf ("Error in check_one for sh=%d, fi=%d\n", sh, fi);
- printf (" f = "); mpfr_dump (f);
- printf ("expected "); mpz_dump (ex);
- printf (" got "); mpz_dump (got);
- printf ("Expected inex ~ %d, got %d (%s)\n",
- inex, ex_inex, same ? "OK" : "wrong");
- printf ("Flags:\n");
- printf (" in"); flags_out (gt_flags);
- printf ("expected"); flags_out (ex_flags);
- printf (" got"); flags_out (gt_flags);
- exit (1);
+ if (e)
+ {
+ mpfr_exp_t ef;
+
+ if (MPFR_IS_ZERO (f))
+ break;
+ ef = MPFR_GET_EXP (f);
+ set_emin (ef);
+ set_emax (ef);
+ }
+ ex_flags = __gmpfr_flags = flags[fi];
+ if (ex_inex != 0)
+ ex_flags |= MPFR_FLAGS_INEXACT;
+ inex = mpfr_get_z (got, f, (mpfr_rnd_t) rnd);
+ inex = VSIGN (inex);
+ gt_flags = __gmpfr_flags;
+ set_emin (emin);
+ set_emax (emax);
+ same = SAME_SIGN (inex, ex_inex);
+
+ if (mpz_cmp (got, ex) != 0 ||
+ !same || gt_flags != ex_flags)
+ {
+ printf ("Error in check_one for sh=%d, fi=%d, %s%s\n",
+ sh, fi,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd),
+ e ? ", reduced exponent range" : "");
+ printf (" f = "); mpfr_dump (f);
+ printf ("expected "); mpz_dump (ex);
+ printf (" got "); mpz_dump (got);
+ printf ("Expected inex ~ %d, got %d (%s)\n",
+ ex_inex, inex, same ? "OK" : "wrong");
+ printf ("Flags:\n");
+ printf (" in"); flags_out (flags[fi]);
+ printf ("expected"); flags_out (ex_flags);
+ printf (" got"); flags_out (gt_flags);
+ exit (1);
+ }
}
- }
+ }
- mpz_neg (ex, ex);
mpfr_neg (f, f, MPFR_RNDN);
}
}
@@ -157,6 +206,7 @@ check_one (mpz_ptr z)
mpfr_clear (f);
mpz_clear (got);
mpz_clear (ex);
+ mpz_clear (t);
}
static void
@@ -169,6 +219,9 @@ check (void)
mpz_set_ui (z, 0L);
check_one (z);
+ mpz_set_si (z, 17L);
+ check_one (z);
+
mpz_set_si (z, 123L);
check_one (z);