From 140fa08a162cb62aee9f63d325d78f77b3803aba Mon Sep 17 00:00:00 2001 From: vlefevre Date: Sat, 23 Dec 2017 10:15:10 +0000 Subject: Merged changesets r12046-12048 from the trunk (bug fix and test). git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/branches/4.0@12049 280ebfd0-de03-0410-8827-d642c229c3f4 --- src/exp_2.c | 13 +++++++------ src/subnormal.c | 5 ++++- tests/texp.c | 20 ++++++++++++++++++++ 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/exp_2.c b/src/exp_2.c index a9439b8b0..64a9fd286 100644 --- a/src/exp_2.c +++ b/src/exp_2.c @@ -198,14 +198,15 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode) mpfr_sub (r, x, r, MPFR_RNDU); + while (MPFR_IS_PURE_FP(r) && MPFR_IS_NEG (r)) + { /* initial approximation n was too large */ + n--; + mpfr_add (r, r, s, MPFR_RNDU); + } + + /* if r is 0, we cannot round correctly */ if (MPFR_LIKELY(MPFR_IS_PURE_FP (r))) { - while (MPFR_IS_NEG (r)) - { /* initial approximation n was too large */ - n--; - mpfr_add (r, r, s, MPFR_RNDU); - } - /* since there was a cancellation in x - n*log(2), the low error_r bits from r are zero and thus non significant, thus we can reduce the working precision */ diff --git a/src/subnormal.c b/src/subnormal.c index 0a135aa9f..1b75ce8b7 100644 --- a/src/subnormal.c +++ b/src/subnormal.c @@ -145,7 +145,10 @@ mpfr_subnormalize (mpfr_ptr y, int old_inexact, mpfr_rnd_t rnd) if (SAME_SIGN (inexact, MPFR_INT_SIGN (y))) mpfr_nexttozero (dest); else /* subnormal range, thus no overflow */ - mpfr_nexttoinf (dest); + { + mpfr_nexttoinf (dest); + MPFR_ASSERTD(!MPFR_IS_INF (dest)); + } inexact = -inexact; } } diff --git a/tests/texp.c b/tests/texp.c index 1d002bd2e..b27e51068 100644 --- a/tests/texp.c +++ b/tests/texp.c @@ -972,6 +972,24 @@ underflow (void) } } +/* bug found with GMP_CHECK_RANDOMIZE=1514290185 */ +static void +bug20171223 (void) +{ + mpfr_t x, y; + int inex; + + mpfr_init2 (x, 372); + mpfr_init2 (y, 2); + mpfr_set_str (x, "-6.9314716128384587678466323621915206417385796077947874471662159283492445979241549847386366371775938082803907383582e-01", 10, MPFR_RNDN); + /* exp(x) = 0.500000009638..., should be rounded to 0.5 */ + inex = mpfr_exp (y, x, MPFR_RNDD); + MPFR_ASSERTN(mpfr_cmp_ui_2exp (y, 1, -1) == 0); + MPFR_ASSERTN(inex < 0); + mpfr_clear (x); + mpfr_clear (y); +} + int main (int argc, char *argv[]) { @@ -980,6 +998,8 @@ main (int argc, char *argv[]) if (argc > 1) check_large (); + bug20171223 (); + check_inexact (); check_special (); -- cgit v1.2.1