summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2021-02-15 22:17:31 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2021-02-15 22:17:31 +0000
commit2240e86e9e2dea5ea5d5dfb98d437b54ff79d87d (patch)
treedfff32c6e5353275c08e111ed43f1996d6797075
parentfed1e21defe65cd76d873f3db3ea28ab456e03c9 (diff)
downloadmpfr-2240e86e9e2dea5ea5d5dfb98d437b54ff79d87d.tar.gz
[src/jyn_asympt.c] Fixed bug when s=0 at the end of the for loop.
[tests/mpfr-test.h] Added mpfr_cmp_si_2exp0 macro (check NaN). [tests/tj1.c] Added testcase. (merged changesets r14431,14434 from the trunk) git-svn-id: https://scm.gforge.inria.fr/anonscm/svn/mpfr/branches/4.1@14436 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r--src/jyn_asympt.c10
-rw-r--r--tests/mpfr-test.h2
-rw-r--r--tests/tj1.c26
3 files changed, 31 insertions, 7 deletions
diff --git a/src/jyn_asympt.c b/src/jyn_asympt.c
index 6e5c7c37d..1f6f4cbb3 100644
--- a/src/jyn_asympt.c
+++ b/src/jyn_asympt.c
@@ -69,7 +69,7 @@ FUNCTION (mpfr_ptr res, long n, mpfr_srcptr z, mpfr_rnd_t r)
MPFR_ZIV_INIT (loop, w);
for (;;)
{
- int ok = 1;
+ int ok = 0;
mpfr_set_prec (c, w);
mpfr_init2 (s, w);
@@ -96,10 +96,7 @@ FUNCTION (mpfr_ptr res, long n, mpfr_srcptr z, mpfr_rnd_t r)
/* if s or c is zero, MPFR_GET_EXP will fail below */
if (MPFR_IS_ZERO(s) || MPFR_IS_ZERO(c))
- {
- ok = 0;
- goto clear;
- }
+ goto clear; /* with ok=0 */
/* precompute 1/(8|z|) */
mpfr_si_div (iz, MPFR_IS_POS(z) ? 1 : -1, z, MPFR_RNDN); /* err <= 1 */
@@ -227,6 +224,9 @@ FUNCTION (mpfr_ptr res, long n, mpfr_srcptr z, mpfr_rnd_t r)
mpfr_sub (s, c, s, MPFR_RNDN);
#endif
}
+ if (MPFR_IS_ZERO(s))
+ goto clear; /* with ok=0 */
+ ok = 1;
if ((n & 2) != 0)
mpfr_neg (s, s, MPFR_RNDN);
if (MPFR_GET_EXP (s) > err)
diff --git a/tests/mpfr-test.h b/tests/mpfr-test.h
index 570e095a5..0103e8ba9 100644
--- a/tests/mpfr-test.h
+++ b/tests/mpfr-test.h
@@ -191,6 +191,8 @@ int mpfr_cmp_str (mpfr_srcptr x, const char *, int, mpfr_rnd_t);
#define mpfr_cmp0(x,y) (MPFR_ASSERTN (!MPFR_IS_NAN (x) && !MPFR_IS_NAN (y)), mpfr_cmp (x,y))
#define mpfr_cmp_ui0(x,i) (MPFR_ASSERTN (!MPFR_IS_NAN (x)), mpfr_cmp_ui (x,i))
+#define mpfr_cmp_si_2exp0(x,i,e) (MPFR_ASSERTN (!MPFR_IS_NAN (x)), \
+ mpfr_cmp_si_2exp (x,i,e))
/* define CHECK_EXTERNAL if you want to check mpfr against another library
with correct rounding. You'll probably have to modify mpfr_print_raw()
diff --git a/tests/tj1.c b/tests/tj1.c
index 880da58a3..1fea6928e 100644
--- a/tests/tj1.c
+++ b/tests/tj1.c
@@ -55,14 +55,14 @@ test_small (void)
/* since |x| is just above 2^e, |j1(x)| is just above 2^(e-1),
thus y should be 2^(e-1) and the inexact flag should be
of opposite sign of x */
- MPFR_ASSERTN(mpfr_cmp_si_2exp (y, sign, e - 1) == 0);
+ MPFR_ASSERTN(mpfr_cmp_si_2exp0 (y, sign, e - 1) == 0);
MPFR_ASSERTN(VSIGN (inex) * sign < 0);
}
else
{
/* here |y| should be 0.5*2^emin and the inexact flag should
have the sign of x */
- MPFR_ASSERTN(mpfr_cmp_si_2exp (y, sign, e) == 0);
+ MPFR_ASSERTN(mpfr_cmp_si_2exp0 (y, sign, e) == 0);
MPFR_ASSERTN(VSIGN (inex) * sign > 0);
}
}
@@ -72,6 +72,26 @@ test_small (void)
mpfr_clear (y);
}
+/* a test that fails with GMP_CHECK_RANDOMIZE=1613146232984428
+ on revision 14429 */
+static void
+bug20210215 (void)
+{
+ mpfr_t x, y;
+ int inex;
+
+ mpfr_init2 (x, 221);
+ mpfr_init2 (y, 1);
+ mpfr_set_str (x, "1.6484611511696130037307738844228498447763863563070374544054791168614e+01", 10, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inex = mpfr_j1 (y, x, MPFR_RNDZ);
+ MPFR_ASSERTN (mpfr_cmp_si_2exp0 (y, -1, -9) == 0);
+ MPFR_ASSERTN (inex > 0);
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_INEXACT);
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
int
main (int argc, char *argv[])
{
@@ -79,6 +99,8 @@ main (int argc, char *argv[])
tests_start_mpfr ();
+ bug20210215 ();
+
test_small ();
mpfr_init (x);