summaryrefslogtreecommitdiff
path: root/exp.c
diff options
context:
space:
mode:
authorzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>1999-10-14 13:26:40 +0000
committerzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>1999-10-14 13:26:40 +0000
commit7823f69e0aacdc94f16f4d191fe4590570baae0b (patch)
tree53ceaa41969bfdb065a31ae819e57d2eda76cad5 /exp.c
parent3188589dd37e83b26d626c49af047b6ffffe4763 (diff)
downloadmpfr-7823f69e0aacdc94f16f4d191fe4590570baae0b.tar.gz
fixed bug when initial approx. floor(x/log(2)) is too large
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@386 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'exp.c')
-rw-r--r--exp.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/exp.c b/exp.c
index b0ad5115f..82bbce7dc 100644
--- a/exp.c
+++ b/exp.c
@@ -83,11 +83,11 @@ mpfr_exp(y, x, rnd_mode)
printf("n=%d K=%d l=%d q=%d\n",n,K,l,q);
#endif
- mpfr_log2(r, GMP_RNDZ);
+ mpfr_log2(s, GMP_RNDZ);
#ifdef DEBUG
- printf("n=%d r=",n); mpfr_print_raw(r); putchar('\n');
+ printf("n=%d log(2)=",n); mpfr_print_raw(s); putchar('\n');
#endif
- mpfr_mul_ui(r, r, (n<0) ? -n : n, GMP_RNDZ); /* r = n*log(2) */
+ mpfr_mul_ui(r, s, (n<0) ? -n : n, GMP_RNDZ); /* r = n*log(2) */
if (n<0) mpfr_neg(r, r, GMP_RNDD);
#ifdef DEBUG
@@ -96,6 +96,12 @@ mpfr_exp(y, x, rnd_mode)
printf(" ="); mpfr_print_raw(r); putchar('\n');
#endif
mpfr_sub(r, x, r, GMP_RNDU);
+ if (SIGN(r)<0) { /* initial approximation n was too large */
+ n--;
+ mpfr_mul_ui(r, s, (n<0) ? -n : n, GMP_RNDZ);
+ if (n<0) mpfr_neg(r, r, GMP_RNDD);
+ mpfr_sub(r, x, r, GMP_RNDU);
+ }
#ifdef DEBUG
printf("x-r=%1.20e\n",mpfr_get_d(r));
if (SIGN(r)<0) { fprintf(stderr,"Error in mpfr_exp: r<0\n"); exit(1); }