summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2004-02-16 17:12:45 +0000
committerzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2004-02-16 17:12:45 +0000
commit5094d98158eff8a199b86a34bc1a00a8308fbfe9 (patch)
treeaa0d778d07058b4827cc375c5f7dda96d62623b2
parent8b524829df9b1eb43cd0ef29a378face7e97e17f (diff)
downloadmpfr-5094d98158eff8a199b86a34bc1a00a8308fbfe9.tar.gz
deal with overflow/underflow in mpfr_div
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@2734 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r--div.c14
-rw-r--r--set_d.c4
-rw-r--r--set_q.c2
3 files changed, 17 insertions, 3 deletions
diff --git a/div.c b/div.c
index 4f5c9db5e..1ccfae8f7 100644
--- a/div.c
+++ b/div.c
@@ -444,7 +444,19 @@ mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mp_rnd_t rnd_mode)
TMP_FREE (marker);
MPFR_MANT(q)[0] &= ~((MPFR_LIMB_ONE << rw) - MPFR_LIMB_ONE);
- MPFR_SET_EXP (q, qexp);
+ MPFR_EXP(q) = qexp;
+
+ /* check for underflow/overflow */
+
+ if (MPFR_UNLIKELY(qexp > __gmpfr_emax))
+ inex = mpfr_set_overflow (q, rnd_mode, sign_quotient);
+ else if (MPFR_UNLIKELY(qexp < __gmpfr_emin))
+ {
+ if (rnd_mode == GMP_RNDN && ((qexp < __gmpfr_emin - 1) ||
+ (inex == 0 && mpfr_powerof2_raw (q))))
+ rnd_mode = GMP_RNDZ;
+ inex = mpfr_set_underflow (q, rnd_mode, sign_quotient);
+ }
MPFR_RET(inex);
}
diff --git a/set_d.c b/set_d.c
index 4db207a2d..713326cdc 100644
--- a/set_d.c
+++ b/set_d.c
@@ -206,6 +206,8 @@ mpfr_set_d (mpfr_ptr r, double d, mp_rnd_t rnd_mode)
/* now d is neither 0, nor NaN nor Inf */
+ mpfr_save_emin_emax ();
+
/* warning: don't use tmp=r here, even if SIZE(r) >= MPFR_LIMBS_PER_DOUBLE,
since PREC(r) may be different from PREC(tmp), and then both variables
would have same precision in the mpfr_set4 call below. */
@@ -253,5 +255,7 @@ mpfr_set_d (mpfr_ptr r, double d, mp_rnd_t rnd_mode)
/* tmp is exact since PREC(tmp)=53 */
inexact = mpfr_set4 (r, tmp, rnd_mode, signd);
+ mpfr_restore_emin_emax ();
+
return mpfr_check_range (r, inexact, rnd_mode);
}
diff --git a/set_q.c b/set_q.c
index 54cc4a9fd..a8b58b33e 100644
--- a/set_q.c
+++ b/set_q.c
@@ -46,7 +46,6 @@ mpfr_set_q (mpfr_ptr f, mpq_srcptr q, mp_rnd_t rnd)
if (prec < MPFR_PREC_MIN)
prec = MPFR_PREC_MIN;
mpfr_init2 (n, prec);
- __gmpfr_emax = prec;
MPFR_ASSERTN(mpfr_set_z (n, num, GMP_RNDZ) == 0);
/* result is exact: overflow cannot occur since emax = prec */
@@ -54,7 +53,6 @@ mpfr_set_q (mpfr_ptr f, mpq_srcptr q, mp_rnd_t rnd)
if (prec < MPFR_PREC_MIN)
prec = MPFR_PREC_MIN;
mpfr_init2 (d, prec);
- __gmpfr_emax = prec;
MPFR_ASSERTN(mpfr_set_z (d, den, GMP_RNDZ) == 0);
/* result is exact: overflow cannot occur, as above */