diff options
author | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2001-11-16 10:06:38 +0000 |
---|---|---|
committer | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2001-11-16 10:06:38 +0000 |
commit | ce6209780460d98d6f6ff59ca215d2c9f962a3f6 (patch) | |
tree | 0d0a96d43963beaba905372dd13148200465b8d5 /log2.c | |
parent | 61c0600496ccd4f7089f768f367bb9499f6bf6f3 (diff) | |
download | mpfr-ce6209780460d98d6f6ff59ca215d2c9f962a3f6.tar.gz |
added static to local functions
explained threshold
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@1505 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'log2.c')
-rw-r--r-- | log2.c | 78 |
1 files changed, 45 insertions, 33 deletions
@@ -30,8 +30,8 @@ mpfr_t __mpfr_const_log2; /* stored value of log(2) */ int __mpfr_const_log2_prec=0; /* precision of stored value */ mp_rnd_t __mpfr_const_log2_rnd; /* rounding mode of stored value */ -int mpfr_aux_log2 _PROTO ((mpfr_ptr, mpz_srcptr, int, int)); -int mpfr_const_aux_log2 _PROTO ((mpfr_ptr, mp_rnd_t)); +static int mpfr_aux_log2 _PROTO ((mpfr_ptr, mpz_srcptr, int, int)); +static int mpfr_const_aux_log2 _PROTO ((mpfr_ptr, mp_rnd_t)); #define A #define A1 1 @@ -53,7 +53,7 @@ int mpfr_const_aux_log2 _PROTO ((mpfr_ptr, mp_rnd_t)); #undef C1 #undef C2 -int +static int #if __STDC__ mpfr_const_aux_log2 (mpfr_ptr mylog, mp_rnd_t rnd_mode) #else @@ -112,6 +112,11 @@ mpfr_const_aux_log2 (mylog, rnd_mode) return 0; } +/* Cross-over point from nai"ve Taylor series to binary splitting, + obtained experimentally on a Pentium II. Optimal value for + target machine should be determined by tuneup. */ +#define LOG2_THRESHOLD 25000 + /* set x to log(2) rounded to precision MPFR_PREC(x) with direction rnd_mode use formula log(2) = sum(1/k/2^k, k=1..infinity) @@ -147,38 +152,45 @@ mpfr_const_log2 (x, rnd_mode) mpfr_ptr x; mp_rnd_t rnd_mode; } /* need to recompute */ - if (precx < 30000){ /* use nai"ve Taylor series evaluation */ - N=2; - do { - oldN = N; - N = precx + _mpfr_ceil_log2 ((double) N); - } while (N != oldN); - mpz_init (s); /* set to zero */ - mpz_init (u); - mpz_init_set_ui (t, 1); - - /* use log(2) = sum((6*k-1)/(2*k^2-k)/2^(2*k+1), k=1..infinity) */ - mpz_mul_2exp (t, t, N-1); - for (k=1; k<N/2; k++) { - mpz_div_2exp (t, t, 2); - mpz_mul_ui (u, t, 6*k-1); - mpz_fdiv_q_ui (u, u, k*(2*k-1)); - mpz_add (s, s, u); - } - - mpfr_set_z(x, s, rnd_mode); - MPFR_EXP(x) -= N; - mpz_clear(s); mpz_clear(t); mpz_clear(u); - } else + if (precx < LOG2_THRESHOLD) /* use nai"ve Taylor series evaluation */ { - /* use binary splitting method */ - mpfr_const_aux_log2(x, rnd_mode); + N=2; + do + { + oldN = N; + N = precx + _mpfr_ceil_log2 ((double) N); + } + while (N != oldN); + mpz_init (s); /* set to zero */ + mpz_init (u); + mpz_init_set_ui (t, 1); + + /* use log(2) = sum((6*k-1)/(2*k^2-k)/2^(2*k+1), k=1..infinity) */ + mpz_mul_2exp (t, t, N-1); + for (k=1; k<N/2; k++) + { + mpz_div_2exp (t, t, 2); + mpz_mul_ui (u, t, 6*k-1); + mpz_fdiv_q_ui (u, u, k*(2*k-1)); + mpz_add (s, s, u); + } + + mpfr_set_z (x, s, rnd_mode); + MPFR_EXP(x) -= N; + mpz_clear (s); + mpz_clear (t); + mpz_clear (u); } + else /* use binary splitting method */ + mpfr_const_aux_log2(x, rnd_mode); /* store computed value */ - if (__mpfr_const_log2_prec==0) mpfr_init2(__mpfr_const_log2, precx); - else mpfr_set_prec(__mpfr_const_log2, precx); - mpfr_set(__mpfr_const_log2, x, rnd_mode); - __mpfr_const_log2_prec=precx; - __mpfr_const_log2_rnd=rnd_mode; + if (__mpfr_const_log2_prec == 0) + mpfr_init2 (__mpfr_const_log2, precx); + else + mpfr_set_prec (__mpfr_const_log2, precx); + + mpfr_set (__mpfr_const_log2, x, rnd_mode); + __mpfr_const_log2_prec = precx; + __mpfr_const_log2_rnd = rnd_mode; } |