summaryrefslogtreecommitdiff
path: root/Build/source/libs/mpfr/mpfr-src/src/set_ui_2exp.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/mpfr/mpfr-src/src/set_ui_2exp.c')
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/set_ui_2exp.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/Build/source/libs/mpfr/mpfr-src/src/set_ui_2exp.c b/Build/source/libs/mpfr/mpfr-src/src/set_ui_2exp.c
index 29ab03525e4..fa72613abb5 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/set_ui_2exp.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/set_ui_2exp.c
@@ -1,7 +1,7 @@
/* mpfr_set_ui_2exp -- set a MPFR number from a machine unsigned integer with
a shift
-Copyright 2004, 2006-2019 Free Software Foundation, Inc.
+Copyright 2004, 2006-2020 Free Software Foundation, Inc.
Contributed by the AriC and Caramba projects, INRIA.
This file is part of the GNU MPFR Library.
@@ -36,12 +36,21 @@ mpfr_set_ui_2exp (mpfr_ptr x, unsigned long i, mpfr_exp_t e, mpfr_rnd_t rnd_mode
}
else
{
+#ifdef MPFR_LONG_WITHIN_LIMB
mp_size_t xn;
int cnt, nbits;
mp_limb_t *xp;
int inex = 0;
- /* FIXME: support int limbs (e.g. 16-bit limbs on 16-bit proc) */
+ /* Early underflow/overflow checking is necessary to avoid
+ integer overflow or errors due to special exponent values. */
+ if (MPFR_UNLIKELY (e < __gmpfr_emin - (mpfr_exp_t)
+ (sizeof (unsigned long) * CHAR_BIT + 1)))
+ return mpfr_underflow (x, rnd_mode == MPFR_RNDN ?
+ MPFR_RNDZ : rnd_mode, i < 0 ? -1 : 1);
+ if (MPFR_UNLIKELY (e >= __gmpfr_emax))
+ return mpfr_overflow (x, rnd_mode, i < 0 ? -1 : 1);
+
MPFR_ASSERTD (i == (mp_limb_t) i);
/* Position of the highest limb */
@@ -68,5 +77,15 @@ mpfr_set_ui_2exp (mpfr_ptr x, unsigned long i, mpfr_exp_t e, mpfr_rnd_t rnd_mode
MPFR_EXP (x) = e;
return mpfr_check_range (x, inex, rnd_mode);
+#else
+ /* if a long does not fit into a limb, we use mpfr_set_z_2exp */
+ mpz_t z;
+ int inex;
+
+ mpz_init_set_ui (z, i);
+ inex = mpfr_set_z_2exp (x, z, e, rnd_mode);
+ mpz_clear (z);
+ return inex;
+#endif
}
}