summaryrefslogtreecommitdiff
path: root/exp3.c
diff options
context:
space:
mode:
authorpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2005-05-11 15:43:40 +0000
committerpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2005-05-11 15:43:40 +0000
commit595e2733810f3c3370be35adf2e61addce8c93c6 (patch)
treef8185550dcf0e1bd3e5503004eb16fabf5ddd151 /exp3.c
parent924f9a3973526ca1beac7ce20b7c7d86e5267763 (diff)
downloadmpfr-595e2733810f3c3370be35adf2e61addce8c93c6.tar.gz
Same patch for exp_3.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@3540 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'exp3.c')
-rw-r--r--exp3.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/exp3.c b/exp3.c
index 9301bcac0..a288d470f 100644
--- a/exp3.c
+++ b/exp3.c
@@ -210,12 +210,38 @@ mpfr_exp_3 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
MPFR_ASSERTN (twopoweri <= LONG_MAX/2);
twopoweri *=2;
}
+
+ mpfr_clear_overflow ();
+ mpfr_clear_underflow ();
for (loop = 0 ; loop < shift_x; loop++)
mpfr_mul (tmp, tmp, tmp, GMP_RNDD);
- if (mpfr_can_round (tmp, realprec, GMP_RNDD, GMP_RNDZ,
+ if (MPFR_UNLIKELY (mpfr_overflow_p ()))
+ {
+ /* We hack to set a FP number outside the valid range so that
+ mpfr_check_range properly generates an overflow */
+ mpfr_setmax (y, __gmpfr_emax);
+ MPFR_EXP (y) ++;
+ inexact = 1;
+ break;
+ }
+ else if (MPFR_UNLIKELY (mpfr_underflow_p ()))
+ {
+ /* We hack to set a FP number outside the valid range so that
+ mpfr_check_range properly generates an underflow.
+ Note that the range has been increased to allow a safe
+ detection of underflow (MPFR_EMIN_MIN-3 in exp.c) even for
+ RNDN */
+ mpfr_setmax (y, MPFR_EMIN_MIN-2);
+ inexact = -1;
+ break;
+ }
+ else if (mpfr_can_round (tmp, realprec, GMP_RNDD, GMP_RNDZ,
MPFR_PREC(y) + (rnd_mode == GMP_RNDN)))
- break;
+ {
+ inexact = mpfr_set (y, tmp, rnd_mode);
+ break;
+ }
MPFR_ZIV_NEXT (ziv_loop, realprec);
Prec = realprec + shift + 2 + shift_x;
mpfr_set_prec (t, Prec);
@@ -223,8 +249,6 @@ mpfr_exp_3 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
}
MPFR_ZIV_FREE (ziv_loop);
- inexact = mpfr_set (y, tmp, rnd_mode);
-
mpz_clear (uk);
mpfr_clear (tmp);
mpfr_clear (t);