diff options
author | pelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4> | 2005-05-11 15:43:40 +0000 |
---|---|---|
committer | pelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4> | 2005-05-11 15:43:40 +0000 |
commit | 595e2733810f3c3370be35adf2e61addce8c93c6 (patch) | |
tree | f8185550dcf0e1bd3e5503004eb16fabf5ddd151 /exp3.c | |
parent | 924f9a3973526ca1beac7ce20b7c7d86e5267763 (diff) | |
download | mpfr-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.c | 32 |
1 files changed, 28 insertions, 4 deletions
@@ -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); |