diff options
author | pelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4> | 2005-02-14 14:18:40 +0000 |
---|---|---|
committer | pelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4> | 2005-02-14 14:18:40 +0000 |
commit | 099491cf0f26d411fc581489cf740b3a75bb8298 (patch) | |
tree | bde3053d8cc9f324b515962ea14bbd4bef62ad94 /pow_si.c | |
parent | de3969c18addea0e0ca2bd9b4c28558df7ab9676 (diff) | |
download | mpfr-099491cf0f26d411fc581489cf740b3a75bb8298.tar.gz |
Clean up code.
Add generic ZivLoop controller.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@3305 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'pow_si.c')
-rw-r--r-- | pow_si.c | 63 |
1 files changed, 33 insertions, 30 deletions
@@ -35,7 +35,7 @@ mpfr_pow_si (mpfr_ptr y, mpfr_srcptr x, long int n, mp_rnd_t rnd_mode) return mpfr_pow_ui (y, x, n, rnd_mode); else { - if (MPFR_UNLIKELY( MPFR_IS_SINGULAR(x) )) + if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x))) { if (MPFR_IS_NAN (x)) { @@ -53,7 +53,7 @@ mpfr_pow_si (mpfr_ptr y, mpfr_srcptr x, long int n, mp_rnd_t rnd_mode) } else /* x is zero */ { - MPFR_ASSERTD (MPFR_IS_ZERO(x)); + MPFR_ASSERTD (MPFR_IS_ZERO (x)); MPFR_SET_INF(y); if (MPFR_IS_POS (x) || ((unsigned) n & 1) == 0) MPFR_SET_POS (y); @@ -62,7 +62,7 @@ mpfr_pow_si (mpfr_ptr y, mpfr_srcptr x, long int n, mp_rnd_t rnd_mode) MPFR_RET(0); } } - MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS (y); /* detect exact powers: x^(-n) is exact iff x is a power of 2 */ if (mpfr_cmp_si_2exp (x, MPFR_SIGN(x), MPFR_EXP(x) - 1) == 0) @@ -73,13 +73,13 @@ mpfr_pow_si (mpfr_ptr y, mpfr_srcptr x, long int n, mp_rnd_t rnd_mode) expx --; MPFR_ASSERTD (n < 0); /* Warning n*expx may overflow! - Many systems abort with LONG_MIN / 1 or LONG_MIN/-1*/ + Some systems abort with LONG_MIN / 1 or LONG_MIN/-1*/ if (n != -1 && expx > 0 && -expx < MPFR_EXP_MIN / (-n)) MPFR_EXP (y) = MPFR_EMIN_MIN - 1; /* Underflow */ else if (n != -1 && expx < 0 && -expx > MPFR_EXP_MAX / (-n)) MPFR_EXP (y) = MPFR_EMAX_MAX + 1; /* Overflow */ else - MPFR_EXP(y) += n * expx; + MPFR_EXP (y) += n * expx; return mpfr_check_range (y, 0, rnd_mode); } @@ -89,18 +89,17 @@ mpfr_pow_si (mpfr_ptr y, mpfr_srcptr x, long int n, mp_rnd_t rnd_mode) { /* Declaration of the intermediary variable */ mpfr_t t; - /* Declaration of the size variable */ - mp_prec_t Nx = MPFR_PREC(x); /* Precision of input variable */ - mp_prec_t Ny = MPFR_PREC(y); /* Precision of output variable */ - - mp_prec_t Nt; /* Precision of the intermediary variable */ - long int err; /* Precision of error */ + mp_prec_t Nx = MPFR_PREC (x); /* Precision of input variable */ + mp_prec_t Ny = MPFR_PREC (y); /* Precision of output variable */ + mp_prec_t Nt; /* Precision of the intermediary variable */ + mp_exp_t err; /* Precision of error */ int inexact; MPFR_SAVE_EXPO_DECL (expo); + MPFR_ZIV_DECL (loop); /* compute the precision of intermediary variable */ - Nt = MAX(Nx,Ny); + Nt = MAX (Nx, Ny); /* the optimal number of bits : see algorithms.ps */ Nt = Nt + 3 + MPFR_INT_CEIL_LOG2 (Nt); @@ -108,24 +107,28 @@ mpfr_pow_si (mpfr_ptr y, mpfr_srcptr x, long int n, mp_rnd_t rnd_mode) /* initialise of intermediary variable */ mpfr_init2 (t, Nt); - - do { - /* reactualisation of the precision */ - mpfr_set_prec (t, Nt); - - /* compute 1/(x^n) n>0*/ - mpfr_pow_ui (t, x, (unsigned long int) n, GMP_RNDN); - inexact = MPFR_IS_ZERO (t) || MPFR_IS_INF (t); - mpfr_ui_div (t, 1, t, GMP_RNDN); - inexact = inexact || MPFR_IS_ZERO (t) || MPFR_IS_INF (t); - /* error estimate -- see pow function in algorithms.ps */ - err = Nt - 3; - - /* actualisation of the precision */ - Nt += BITS_PER_MP_LIMB; - } while (inexact == 0 && - !mpfr_can_round (t, err, GMP_RNDN, GMP_RNDZ, - Ny + (rnd_mode == GMP_RNDN))); + + MPFR_ZIV_INIT (loop, Nt); + for (;;) + { + /* compute 1/(x^n) n>0*/ + mpfr_pow_ui (t, x, (unsigned long int) n, GMP_RNDN); + inexact = MPFR_IS_ZERO (t) || MPFR_IS_INF (t); + mpfr_ui_div (t, 1, t, GMP_RNDN); + inexact = inexact || MPFR_IS_ZERO (t) || MPFR_IS_INF (t); + + /* error estimate -- see pow function in algorithms.ps */ + err = Nt - 3; + if (MPFR_LIKELY (inexact != 0 + || mpfr_can_round (t, err, GMP_RNDN, GMP_RNDZ, + Ny + (rnd_mode == GMP_RNDN)))) + break; + + /* actualisation of the precision */ + Nt += BITS_PER_MP_LIMB; + mpfr_set_prec (t, Nt); + } + MPFR_ZIV_FREE (loop); inexact = mpfr_set (y, t, rnd_mode); mpfr_clear (t); |