summaryrefslogtreecommitdiff
path: root/cos.c
diff options
context:
space:
mode:
authorzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2004-05-18 16:00:28 +0000
committerzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2004-05-18 16:00:28 +0000
commite03bfb0c08d5459d340e5af1d47ac70c1935bdf3 (patch)
tree616ec219ea85ad7217fe88b062a9c567bb52637f /cos.c
parente3261b4b069994ceaecf4e46033b7a1e3f3517fc (diff)
downloadmpfr-e03bfb0c08d5459d340e5af1d47ac70c1935bdf3.tar.gz
fixed problem for x near from Pi/2 (the internal precision should take
into account the cancellation) git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@2918 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'cos.c')
-rw-r--r--cos.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/cos.c b/cos.c
index 4c1f3c129..6e82107a8 100644
--- a/cos.c
+++ b/cos.c
@@ -32,6 +32,7 @@ mpfr_cos (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
mpfr_t r, s;
mp_limb_t *rp, *sp;
mp_size_t sm;
+ mp_exp_t exps, cancel = 0;
TMP_DECL (marker);
if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(x)))
@@ -84,12 +85,18 @@ mpfr_cos (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode)
k++;
/* now the error is bounded by 2^(k-m) = 2^(EXP(s)-err) */
- if (MPFR_LIKELY(mpfr_can_round (s, MPFR_GET_EXP(s)+m-k,GMP_RNDN,GMP_RNDZ,
+ exps = MPFR_GET_EXP(s);
+ if (MPFR_LIKELY(mpfr_can_round (s, exps + m - k, GMP_RNDN, GMP_RNDZ,
precy + (rnd_mode == GMP_RNDN))))
break;
m += BITS_PER_MP_LIMB;
- sm++;
+ if (exps < cancel)
+ {
+ m += cancel - exps;
+ cancel = exps;
+ }
+ sm = (m + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB;
MPFR_TMP_INIT(rp, r, m, sm);
MPFR_TMP_INIT(sp, s, m, sm);
}