diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2018-09-14 21:46:06 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2018-09-14 21:46:06 +0000 |
commit | 26b09935e32156a042852307239101d0d99a3c08 (patch) | |
tree | da2d08d50b18294ffac097a5f3be12baa9f803d7 | |
parent | 3aa0008740f848c5ac60ac05d4983e7e666a3af0 (diff) | |
download | mpfr-26b09935e32156a042852307239101d0d99a3c08.tar.gz |
[src/get_si.c] Code refactoring/simplification like what has been
done for get_ui.c in r13185, fixing also an integer overflow when
MPFR_LONG_WITHIN_LIMB is not defined.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@13200 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r-- | src/get_si.c | 48 |
1 files changed, 18 insertions, 30 deletions
diff --git a/src/get_si.c b/src/get_si.c index eff3c33a2..05ccecce6 100644 --- a/src/get_si.c +++ b/src/get_si.c @@ -57,44 +57,32 @@ mpfr_get_si (mpfr_srcptr f, mpfr_rnd_t rnd) MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags); /* warning: if x=0, taking its exponent is illegal */ - if (MPFR_UNLIKELY (MPFR_IS_ZERO(x))) + if (MPFR_IS_ZERO (x)) s = 0; else -#ifdef MPFR_LONG_WITHIN_LIMB { - mp_limb_t a; + unsigned long u = 0; mp_size_t n; mpfr_exp_t exp; - /* now the result is in the most significant limb of x */ - exp = MPFR_GET_EXP (x); /* since |x| >= 1, exp >= 1 */ - n = MPFR_LIMB_SIZE(x); - a = MPFR_MANT(x)[n - 1] >> (GMP_NUMB_BITS - exp); - s = MPFR_IS_POS (f) ? a : a <= LONG_MAX ? - (long) a : LONG_MIN; - } + exp = MPFR_GET_EXP (x); + MPFR_ASSERTD (exp >= 1); /* since |x| >= 1 */ + n = MPFR_LIMB_SIZE (x); +#ifdef MPFR_LONG_WITHIN_LIMB + MPFR_ASSERTD (exp <= GMP_NUMB_BITS); #else - { - mp_size_t n; - mpfr_exp_t exp; - - exp = MPFR_GET_EXP (x); - n = MPFR_LIMB_SIZE(x); - /* invariant: the current word x[n-1] has to be multiplied by - 2^(exp - GMP_NUMB_BITS) */ - s = 0; - while (exp > 0) - { - MPFR_ASSERTD(n > 0); - if (exp <= GMP_NUMB_BITS) - s += MPFR_MANT(x)[n - 1] >> (GMP_NUMB_BITS - exp); - else - s += (unsigned long) MPFR_MANT(x)[n - 1] << (exp - GMP_NUMB_BITS); - n --; - exp -= GMP_NUMB_BITS; - } - s = MPFR_IS_POS (f) ? s : s <= LONG_MAX ? - (long) s : LONG_MIN; - } + while (exp > GMP_NUMB_BITS) + { + MPFR_ASSERTD (n > 0); + u += (unsigned long) MPFR_MANT(x)[n - 1] << (exp - GMP_NUMB_BITS); + n--; + exp -= GMP_NUMB_BITS; + } #endif + MPFR_ASSERTD (n > 0); + u += MPFR_MANT(x)[n - 1] >> (GMP_NUMB_BITS - exp); + s = MPFR_IS_POS (f) ? u : u <= LONG_MAX ? - (long) u : LONG_MIN; + } mpfr_clear (x); |