summaryrefslogtreecommitdiff
path: root/pow_ui.c
diff options
context:
space:
mode:
authorzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2003-10-14 11:49:06 +0000
committerzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2003-10-14 11:49:06 +0000
commit1fa2277c10582baa8b8402b8cf1702116ccbc560 (patch)
tree672209195ecad922dc489260098588b4dca469ad /pow_ui.c
parent51aef80e83eaf2fc76dd6be59c0549e890dccd2b (diff)
downloadmpfr-1fa2277c10582baa8b8402b8cf1702116ccbc560.tar.gz
replaced mpfr_can_round (approx, err, rnd1, GMP_RNDN, prec)
by mpfr_can_round (approx, err, rnd1, GMP_RNDZ, prec + 1) which in addition guarantees a correct inexact flag git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@2492 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'pow_ui.c')
-rw-r--r--pow_ui.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/pow_ui.c b/pow_ui.c
index bbce707a1..aa8db2020 100644
--- a/pow_ui.c
+++ b/pow_ui.c
@@ -44,7 +44,7 @@ mpfr_pow_ui (mpfr_ptr x, mpfr_srcptr y, unsigned long int n, mp_rnd_t rnd)
MPFR_CLEAR_NAN(x);
- if (n == 0) /* x^0 = 1 for any x */
+ if (n == 0) /* y^0 = 1 for any y */
{
/* The return mpfr_set_ui is important as 1 isn't necessarily
in the exponent range. */
@@ -64,6 +64,12 @@ mpfr_pow_ui (mpfr_ptr x, mpfr_srcptr y, unsigned long int n, mp_rnd_t rnd)
MPFR_CLEAR_INF(x);
+ if (MPFR_IS_ZERO(y)) /* 0^n = 0 for any n */
+ {
+ MPFR_SET_ZERO(x);
+ MPFR_RET(0);
+ }
+
mpfr_save_emin_emax ();
mpfr_init (res);
@@ -88,16 +94,23 @@ mpfr_pow_ui (mpfr_ptr x, mpfr_srcptr y, unsigned long int n, mp_rnd_t rnd)
if (mpfr_mul (res, res, y, rnd1))
inexact = 1;
}
+
+ /* check underflow */
+ if (MPFR_EXP(res) <= (double) __gmpfr_emin)
+ {
+ mpfr_clear (res);
+ mpfr_restore_emin_emax ();
+ return mpfr_set_underflow (x, rnd, (n % 2) ? MPFR_SIGN(y) : 1);
+ }
+
err = prec - err;
if (err < 0)
err = 0;
}
- while (inexact &&
- mpfr_can_round (res, err, MPFR_SIGN(res) > 0 ? GMP_RNDU : GMP_RNDD,
- rnd, MPFR_PREC(x)) == 0);
+ while (inexact && !mpfr_can_round (res, err, GMP_RNDN, GMP_RNDZ,
+ MPFR_PREC(x) + (rnd == GMP_RNDN)));
- if (mpfr_set (x, res, rnd))
- inexact = 1;
+ inexact = mpfr_set (x, res, rnd);
mpfr_clear (res);
mpfr_restore_emin_emax ();
return mpfr_check_range (x, inexact, rnd);