summaryrefslogtreecommitdiff
path: root/pow_ui.c
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2003-11-04 16:14:47 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2003-11-04 16:14:47 +0000
commitbc3b76bc225273a3d94929207a38d0b4ed43a4f5 (patch)
tree9b6d8550998352d929707ef1da4af244cf1f5fa7 /pow_ui.c
parent6603494a0ea3532c7e23ba0244d0cd0f7fdc9aca (diff)
downloadmpfr-bc3b76bc225273a3d94929207a38d0b4ed43a4f5.tar.gz
Merged the mpfr-2-0-2-branch pow_ui.c changes to the trunk.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@2533 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'pow_ui.c')
-rw-r--r--pow_ui.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/pow_ui.c b/pow_ui.c
index c859f9ad6..4fd4bb909 100644
--- a/pow_ui.c
+++ b/pow_ui.c
@@ -29,10 +29,9 @@ MA 02111-1307, USA. */
int
mpfr_pow_ui (mpfr_ptr x, mpfr_srcptr y, unsigned long int n, mp_rnd_t rnd)
{
- long int i, err;
unsigned long m;
mpfr_t res;
- mp_prec_t prec;
+ mp_prec_t prec, err;
int inexact;
mp_rnd_t rnd1;
@@ -86,33 +85,35 @@ mpfr_pow_ui (mpfr_ptr x, mpfr_srcptr y, unsigned long int n, mp_rnd_t rnd)
do
{
+ int i;
+
prec += 3;
- for (m=n, i=0; m; i++, m>>=1, prec++);
+ for (m = n, i = 0; m; i++, m >>= 1, prec++)
+ ;
mpfr_set_prec (res, prec);
inexact = mpfr_set (res, y, rnd1);
- err = 1;
+ err = prec <= i ? 0 : prec - i;
+ MPFR_ASSERTD (i >= 1);
/* now 2^(i-1) <= n < 2^i */
- for (i-=2; i>=0; i--)
- {
- if (mpfr_mul (res, res, res, GMP_RNDU))
- inexact = 1;
- err++;
- if (n & (1UL << i))
- if (mpfr_mul (res, res, y, rnd1))
- inexact = 1;
- }
+ for (i -= 2; i >= 0; i--)
+ {
+ if (mpfr_mul (res, res, res, GMP_RNDU))
+ inexact = 1;
+ if (n & (1UL << i))
+ if (mpfr_mul (res, res, y, rnd1))
+ inexact = 1;
+ }
+ /* FIXME: infinity and 0 should be checked too. */
+ MPFR_ASSERTN (MPFR_IS_FP (res));
+ MPFR_ASSERTN (MPFR_NOTZERO (res));
/* check underflow */
- if (MPFR_UNLIKELY(MPFR_EXP(res) <= (double) __gmpfr_emin))
+ if (MPFR_UNLIKELY (MPFR_GET_EXP (res) <= __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, GMP_RNDN, GMP_RNDZ,
MPFR_PREC(x) + (rnd == GMP_RNDN)));