summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2005-06-02 15:55:58 +0000
committerpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2005-06-02 15:55:58 +0000
commitfd07d23b8d7a0b98a957ae845793577d21b9b121 (patch)
tree96fa2f522fddf664d9a9d306f7b2e111ef80b79b
parentcb90ed6df03ef290457babe98afca87d40eec97d (diff)
downloadmpfr-fd07d23b8d7a0b98a957ae845793577d21b9b121.tar.gz
Optimize it a few by avoiding calling fac_ui for each iteration
of the main loop. git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@3605 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r--gamma.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/gamma.c b/gamma.c
index b9d6bea32..3f8856f6d 100644
--- a/gamma.c
+++ b/gamma.c
@@ -37,6 +37,7 @@ int
mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr x, mp_rnd_t rnd_mode)
{
mpfr_t xp, GammaTrial, tmp, tmp2;
+ mpz_t fact;
mp_prec_t Prec, prec_gamma, prec_nec, realprec;
mp_prec_t A, N, estimated_cancel;
unsigned long k;
@@ -110,6 +111,7 @@ mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr x, mp_rnd_t rnd_mode)
MPFR_GROUP_INIT_4 (group, realprec + BITS_PER_MP_LIMB,
xp, tmp, tmp2, GammaTrial);
+ mpz_init (fact);
MPFR_ZIV_INIT (loop, realprec);
for (;;)
{
@@ -144,6 +146,7 @@ mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr x, mp_rnd_t rnd_mode)
mpfr_sub (xp, x, __gmpfr_one, GMP_RNDN);
mpfr_set_ui (GammaTrial, 0, GMP_RNDN);
sign = 1;
+ mpz_set_ui (fact, 1);
for (k = 1; k <= N; k++)
{
@@ -153,13 +156,18 @@ mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr x, mp_rnd_t rnd_mode)
mpfr_mul (tmp2, tmp2, tmp, GMP_RNDN);
mpfr_sqrt_ui (tmp, A - k, GMP_RNDN);
mpfr_mul (tmp2, tmp2, tmp, GMP_RNDN);
- mpfr_fac_ui (tmp, k - 1, GMP_RNDN);
- mpfr_div (tmp2, tmp2, tmp, GMP_RNDN);
+ if (k >= 3)
+ {
+ /* mpfr_fac_ui (tmp, k-1, GMP_RNDN); */
+ mpz_mul_ui (fact, fact, k-1);
+ mpfr_set_z (tmp, fact, GMP_RNDN);
+ mpfr_div (tmp2, tmp2, tmp, GMP_RNDN);
+ }
mpfr_add_ui (tmp, xp, k, GMP_RNDN);
mpfr_div (tmp2, tmp2, tmp, GMP_RNDN);
sign = -sign;
if (sign == 1)
- mpfr_neg (tmp2, tmp2, GMP_RNDN);
+ MPFR_CHANGE_SIGN (tmp2);
mpfr_add (GammaTrial, GammaTrial, tmp2, GMP_RNDN);
}
#ifdef DEBUG
@@ -185,7 +193,7 @@ mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr x, mp_rnd_t rnd_mode)
if (compared < 0)
{
mpfr_const_pi (tmp2, GMP_RNDN);
- mpfr_sub_ui (tmp, x, 1, GMP_RNDN);
+ mpfr_sub (tmp, x, __gmpfr_one, GMP_RNDN);
mpfr_mul (tmp, tmp2, tmp, GMP_RNDN);
mpfr_div (GammaTrial, tmp, GammaTrial, GMP_RNDN);
mpfr_sin (tmp, tmp, GMP_RNDN);
@@ -205,6 +213,7 @@ mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr x, mp_rnd_t rnd_mode)
inex = mpfr_set (gamma, GammaTrial, rnd_mode);
MPFR_GROUP_CLEAR (group);
+ mpz_clear (fact);
MPFR_SAVE_EXPO_FREE (expo);
return mpfr_check_range(gamma, inex, rnd_mode);
}