summaryrefslogtreecommitdiff
path: root/const_pi.c
diff options
context:
space:
mode:
authorpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2005-02-14 14:38:06 +0000
committerpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2005-02-14 14:38:06 +0000
commit5bd4cf91abc8e7949c8401d8fd4721769d6b94f8 (patch)
tree6f34de8410044b4c982518cfc43c6111e5ac5873 /const_pi.c
parentd7b63dd56ac727e1be21785e45a96a6d578cbfe7 (diff)
downloadmpfr-5bd4cf91abc8e7949c8401d8fd4721769d6b94f8.tar.gz
Add ZivLoop controller for constantes.
Augment exponent range in the cache. Remove it in const_pi. git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@3308 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'const_pi.c')
-rw-r--r--const_pi.c53
1 files changed, 32 insertions, 21 deletions
diff --git a/const_pi.c b/const_pi.c
index 8cfb54bd9..3194ec767 100644
--- a/const_pi.c
+++ b/const_pi.c
@@ -31,29 +31,30 @@ mpfr_const_pi (mpfr_ptr x, mp_rnd_t rnd_mode) {
return mpfr_cache (x, __gmpfr_cache_const_pi, rnd_mode);
}
+/* Don't need to save/restore exponent range: the cache does it */
int
mpfr_const_pi_internal (mpfr_ptr x, mp_rnd_t rnd_mode)
{
mpfr_t a, A, B, D, S;
mp_prec_t px, p, cancel, k, kmax;
- int inex = 0, ok;
+ MPFR_ZIV_DECL (loop);
+ int inex;
px = MPFR_PREC (x);
/* we need 9*2^kmax - 4 >= px+2*kmax+8 */
for (kmax = 2; ((px + 2 * kmax + 12) / 9) >> kmax; kmax ++);
- p = px + 2 * kmax + 14; /* guarantees no recomputation for px <= 10000 */
-
- do {
- p += kmax;
-
- mpfr_init2 (a, p);
- mpfr_init2 (A, p);
- mpfr_init2 (B, p);
- mpfr_init2 (D, p);
- mpfr_init2 (S, p);
-
+ p = px + 3 * kmax + 14; /* guarantees no recomputation for px <= 10000 */
+
+ mpfr_init2 (a, p);
+ mpfr_init2 (A, p);
+ mpfr_init2 (B, p);
+ mpfr_init2 (D, p);
+ mpfr_init2 (S, p);
+
+ MPFR_ZIV_INIT (loop, p);
+ for (;;) {
mpfr_set_ui (a, 1, GMP_RNDN); /* a = 1 */
mpfr_set_ui (A, 1, GMP_RNDN); /* A = a^2 = 1 */
mpfr_set_ui_2exp (B, 1, -1, GMP_RNDN); /* B = b^2 = 1/2 */
@@ -90,16 +91,26 @@ mpfr_const_pi_internal (mpfr_ptr x, mp_rnd_t rnd_mode)
mpfr_div (A, B, D, GMP_RNDN);
/* MPFR_ASSERTN(p >= 2 * k + 8); */
- if ((ok = mpfr_can_round (A, p - 2 * k - 8, GMP_RNDN, GMP_RNDZ,
- px + (rnd_mode == GMP_RNDN))))
- inex = mpfr_set (x, A, rnd_mode);
+ if (MPFR_LIKELY (mpfr_can_round (A, p - 2 * k - 8, GMP_RNDN, GMP_RNDZ,
+ px + (rnd_mode == GMP_RNDN))))
+ break;
- mpfr_clear (a);
- mpfr_clear (A);
- mpfr_clear (B);
- mpfr_clear (D);
- mpfr_clear (S);
- } while (ok == 0);
+ p += kmax;
+ MPFR_ZIV_NEXT (loop, p);
+ mpfr_set_prec (a, p);
+ mpfr_set_prec (A, p);
+ mpfr_set_prec (B, p);
+ mpfr_set_prec (D, p);
+ mpfr_set_prec (S, p);
+ }
+ MPFR_ZIV_FREE (loop);
+ inex = mpfr_set (x, A, rnd_mode);
+
+ mpfr_clear (a);
+ mpfr_clear (A);
+ mpfr_clear (B);
+ mpfr_clear (D);
+ mpfr_clear (S);
return inex;
}