summaryrefslogtreecommitdiff
path: root/mpn_exp.c
diff options
context:
space:
mode:
authorpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2004-09-28 09:26:34 +0000
committerpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2004-09-28 09:26:34 +0000
commit49755dfe798eafade73ad324123e87ac9abf94b6 (patch)
treed8513c29600c2d61d0acc658ca3394ea00ce0e42 /mpn_exp.c
parent6ad38b945a6b11db9d516dc4a0c9c57a0c1175ed (diff)
downloadmpfr-49755dfe798eafade73ad324123e87ac9abf94b6.tar.gz
Fix how to detect overflow so that it can be build with GCC -ftrapv
option without any bugs (In the previous code, the overflow was detected afterwards, whereas, now, it is detected before). Fix also another real problem of overflow (Addition of two signed integers). git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@3002 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'mpn_exp.c')
-rw-r--r--mpn_exp.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/mpn_exp.c b/mpn_exp.c
index b0bb88cb3..ddead85ea 100644
--- a/mpn_exp.c
+++ b/mpn_exp.c
@@ -95,16 +95,18 @@ mpfr_mpn_exp (mp_limb_t *a, mp_exp_t *exp_r, int b, mp_exp_t e, size_t n)
/* set {c+n, 2n1-n} to 0 : {c, n} = {a, n}^2*K^n */
/* check overflow on f */
- {
- mp_exp_t oldf = f;
- f = 2 * f;
- if (f / 2 != oldf)
- {
- TMP_FREE(marker);
- return -2;
- }
- }
- f += n * BITS_PER_MP_LIMB;
+ if (MPFR_UNLIKELY(f < MPFR_EXP_MIN/2 || f > MPFR_EXP_MAX/2))
+ {
+ overflow:
+ TMP_FREE(marker);
+ return -2;
+ }
+ /* FIXME: Could f = 2*f + n * BITS_PER_MP_LIMB be used? */
+ f = 2*f;
+ MPFR_SADD_OVERFLOW (f, f, n * BITS_PER_MP_LIMB,
+ mp_exp_t, mp_exp_unsigned_t,
+ MPFR_EXP_MIN, MPFR_EXP_MAX,
+ goto overflow, goto overflow);
if ((c[2*n - 1] & MPFR_LIMB_HIGHBIT) == 0)
{
/* shift A by one bit to the left */