diff options
author | pelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4> | 2005-02-14 14:38:06 +0000 |
---|---|---|
committer | pelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4> | 2005-02-14 14:38:06 +0000 |
commit | 5bd4cf91abc8e7949c8401d8fd4721769d6b94f8 (patch) | |
tree | 6f34de8410044b4c982518cfc43c6111e5ac5873 /const_pi.c | |
parent | d7b63dd56ac727e1be21785e45a96a6d578cbfe7 (diff) | |
download | mpfr-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.c | 53 |
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; } |