diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2003-11-04 16:14:47 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2003-11-04 16:14:47 +0000 |
commit | bc3b76bc225273a3d94929207a38d0b4ed43a4f5 (patch) | |
tree | 9b6d8550998352d929707ef1da4af244cf1f5fa7 /pow_ui.c | |
parent | 6603494a0ea3532c7e23ba0244d0cd0f7fdc9aca (diff) | |
download | mpfr-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.c | 37 |
1 files changed, 19 insertions, 18 deletions
@@ -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))); |