summaryrefslogtreecommitdiff
path: root/pow_si.c
diff options
context:
space:
mode:
authorpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2005-02-14 14:18:40 +0000
committerpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2005-02-14 14:18:40 +0000
commit099491cf0f26d411fc581489cf740b3a75bb8298 (patch)
treebde3053d8cc9f324b515962ea14bbd4bef62ad94 /pow_si.c
parentde3969c18addea0e0ca2bd9b4c28558df7ab9676 (diff)
downloadmpfr-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.c63
1 files changed, 33 insertions, 30 deletions
diff --git a/pow_si.c b/pow_si.c
index 8e2ccfa2a..fc4cd3f26 100644
--- a/pow_si.c
+++ b/pow_si.c
@@ -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);