diff options
Diffstat (limited to 'Build/source/libs/mpfr/mpfr-src/src/mul_2ui.c')
-rw-r--r-- | Build/source/libs/mpfr/mpfr-src/src/mul_2ui.c | 36 |
1 files changed, 11 insertions, 25 deletions
diff --git a/Build/source/libs/mpfr/mpfr-src/src/mul_2ui.c b/Build/source/libs/mpfr/mpfr-src/src/mul_2ui.c index ed1191d53c2..11bf3a1d34b 100644 --- a/Build/source/libs/mpfr/mpfr-src/src/mul_2ui.c +++ b/Build/source/libs/mpfr/mpfr-src/src/mul_2ui.c @@ -1,6 +1,6 @@ /* mpfr_mul_2ui -- multiply a floating-point number by a power of two -Copyright 1999, 2001-2019 Free Software Foundation, Inc. +Copyright 1999, 2001-2020 Free Software Foundation, Inc. Contributed by the AriC and Caramba projects, INRIA. This file is part of the GNU MPFR Library. @@ -35,31 +35,17 @@ mpfr_mul_2ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int n, mpfr_rnd_t rnd_mod inexact = (y != x) ? mpfr_set (y, x, rnd_mode) : 0; - if (MPFR_LIKELY( MPFR_IS_PURE_FP(y)) ) + if (MPFR_LIKELY (MPFR_IS_PURE_FP (y))) { - /* n will have to be casted to long to make sure that the addition - and subtraction below (for overflow detection) are signed */ - while (MPFR_UNLIKELY(n > LONG_MAX)) - { - int inex2; - - n -= LONG_MAX; - inex2 = mpfr_mul_2ui(y, y, LONG_MAX, rnd_mode); - if (inex2) - return inex2; /* overflow */ - } - - /* MPFR_EMIN_MIN + (long) n is signed and doesn't lead to an overflow; - the first test useful so that the real test can't lead to an - overflow. */ - { - mpfr_exp_t exp = MPFR_GET_EXP (y); - if (MPFR_UNLIKELY( __gmpfr_emax < MPFR_EMIN_MIN + (long) n || - exp > __gmpfr_emax - (long) n)) - return mpfr_overflow (y, rnd_mode, MPFR_SIGN(y)); - - MPFR_SET_EXP (y, exp + (long) n); - } + mpfr_exp_t exp = MPFR_GET_EXP (y); + mpfr_exp_t diffexp; + + diffexp = __gmpfr_emax - exp; /* diff of two valid exponents */ + if (MPFR_UNLIKELY (n > diffexp)) /* exp + n > emax */ + return mpfr_overflow (y, rnd_mode, MPFR_SIGN (y)); + /* Now, 0 <= n <= diffexp, thus n fits in a mpfr_exp_t, + and exp + n <= emax (no integer overflow). */ + MPFR_SET_EXP (y, exp + (mpfr_exp_t) n); } return inexact; |