summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2018-09-14 21:46:06 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2018-09-14 21:46:06 +0000
commit26b09935e32156a042852307239101d0d99a3c08 (patch)
treeda2d08d50b18294ffac097a5f3be12baa9f803d7
parent3aa0008740f848c5ac60ac05d4983e7e666a3af0 (diff)
downloadmpfr-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.c48
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);