summaryrefslogtreecommitdiff
path: root/cos.c
diff options
context:
space:
mode:
authorzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2005-01-28 10:43:30 +0000
committerzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2005-01-28 10:43:30 +0000
commit74cf25ac3d39815741cadcb56cbf514ccc204190 (patch)
treec126f68fee6aed3964818d509a33d5396685bf6f /cos.c
parent169c07ff459a797e51d4fa0bba1d1a30c2be018f (diff)
downloadmpfr-74cf25ac3d39815741cadcb56cbf514ccc204190.tar.gz
fixed efficiency problem in case of cos(Pi)
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@3230 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'cos.c')
-rw-r--r--cos.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/cos.c b/cos.c
index 059cf7bc6..8b6b9f189 100644
--- a/cos.c
+++ b/cos.c
@@ -69,7 +69,7 @@ int
mpfr_cos (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
{
mp_prec_t K0, K, precy, m, k, l;
- int inexact;
+ int inexact, loops;
mpfr_t r, s;
mp_limb_t *rp, *sp;
mp_size_t sm;
@@ -106,7 +106,7 @@ mpfr_cos (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
MPFR_TMP_INIT(rp, r, m, sm);
MPFR_TMP_INIT(sp, s, m, sm);
- for (;;)
+ for (loops = 1; ; loops++)
{
mpfr_mul (r, x, x, GMP_RNDU); /* err <= 1 ulp */
@@ -136,12 +136,16 @@ mpfr_cos (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
precy + (rnd_mode == GMP_RNDN))))
break;
- m += BITS_PER_MP_LIMB;
if (exps < cancel)
{
m += cancel - exps;
cancel = exps;
}
+ m += BITS_PER_MP_LIMB;
+ /* if we already had two failures, possibly a huge cancellation,
+ for example cos(Pi) */
+ if (loops >= 2)
+ m += m / 2;
sm = (m + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB;
MPFR_TMP_INIT(rp, r, m, sm);