diff options
author | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 1999-10-14 13:26:40 +0000 |
---|---|---|
committer | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 1999-10-14 13:26:40 +0000 |
commit | 7823f69e0aacdc94f16f4d191fe4590570baae0b (patch) | |
tree | 53ceaa41969bfdb065a31ae819e57d2eda76cad5 /exp.c | |
parent | 3188589dd37e83b26d626c49af047b6ffffe4763 (diff) | |
download | mpfr-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.c | 12 |
1 files changed, 9 insertions, 3 deletions
@@ -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); } |