summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2017-08-22 11:57:20 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2017-08-22 11:57:20 +0000
commit3bb61eb7955b075145731fd6835631b316c770a5 (patch)
tree1e2236f257260ce26a8f3f78fb5badd36c122960
parentf29c3ff29bb98e3ae6674000900b4017aa95a4be (diff)
downloadmpfr-3bb61eb7955b075145731fd6835631b316c770a5.tar.gz
[src/urandom.c] Fixed bug reported by Trevor Spiteri:
<https://sympa.inria.fr/sympa/arc/mpfr/2017-01/msg00020.html> [tests/turandom.c] Added non-regression test. (merged changesets r11218-11219,11221 from the trunk) git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/branches/3.1@11648 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r--src/urandom.c8
-rw-r--r--tests/turandom.c20
2 files changed, 24 insertions, 4 deletions
diff --git a/src/urandom.c b/src/urandom.c
index 8ca5f043e..0145be52c 100644
--- a/src/urandom.c
+++ b/src/urandom.c
@@ -87,19 +87,20 @@ mpfr_urandom (mpfr_ptr rop, gmp_randstate_t rstate, mpfr_rnd_t rnd_mode)
count_leading_zeros (cnt, rp[0]);
cnt -= GMP_NUMB_BITS - DRAW_BITS;
}
+ exp -= cnt; /* no integer overflow */
- if (MPFR_UNLIKELY (exp < emin + cnt))
+ if (MPFR_UNLIKELY (exp < emin))
{
/* To get here, we have been drawing more than -emin zeros
in a row, then return 0 or the smallest representable
positive number.
The rounding to nearest mode is subtle:
- If exp - cnt == emin - 1, the rounding bit is set, except
+ If exp == emin - 1, the rounding bit is set, except
if cnt == DRAW_BITS in which case the rounding bit is
outside rp[0] and must be generated. */
if (rnd_mode == MPFR_RNDU || rnd_mode == MPFR_RNDA
- || (rnd_mode == MPFR_RNDN && cnt == exp - emin - 1
+ || (rnd_mode == MPFR_RNDN && exp == emin - 1
&& (cnt != DRAW_BITS || random_rounding_bit (rstate))))
{
mpfr_set_ui_2exp (rop, 1, emin - 1, rnd_mode);
@@ -111,7 +112,6 @@ mpfr_urandom (mpfr_ptr rop, gmp_randstate_t rstate, mpfr_rnd_t rnd_mode)
return -1;
}
}
- exp -= cnt;
}
MPFR_EXP (rop) = exp; /* Warning: may be outside the current
exponent range */
diff --git a/tests/turandom.c b/tests/turandom.c
index 53bb7ee47..ec5ff8ff9 100644
--- a/tests/turandom.c
+++ b/tests/turandom.c
@@ -191,6 +191,24 @@ bug20100914 (void)
gmp_randclear (s);
}
+/* non-regression test for bug reported by Trevor Spiteri
+ https://sympa.inria.fr/sympa/arc/mpfr/2017-01/msg00020.html */
+static void
+bug20170123 (void)
+{
+ mpfr_t x;
+ mpfr_exp_t emin;
+
+ emin = mpfr_get_emin ();
+ mpfr_set_emin (-7);
+ mpfr_init2 (x, 53);
+ gmp_randseed_ui (mpfr_rands, 398);
+ mpfr_urandom (x, mpfr_rands, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui_2exp (x, 1, -8) == 0);
+ mpfr_clear (x);
+ mpfr_set_emin (emin);
+}
+
int
main (int argc, char *argv[])
{
@@ -244,6 +262,8 @@ main (int argc, char *argv[])
bug20100914 ();
+ bug20170123 ();
+
tests_end_mpfr ();
return 0;
}