diff options
author | pelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4> | 2005-07-22 14:01:30 +0000 |
---|---|---|
committer | pelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4> | 2005-07-22 14:01:30 +0000 |
commit | 70e3fa0226e5becaa8b065de5e8e211ac9f4d2c9 (patch) | |
tree | 166658cc935bd8ab1338c75faf77877ac8c757a0 | |
parent | 0a090fba92a11eccb9957a0c19e27e4c03be899c (diff) | |
download | mpfr-70e3fa0226e5becaa8b065de5e8e211ac9f4d2c9.tar.gz |
Fix bug for high values of input (assertion failed)
because erf(x) ~ 1, so 1-erf(x) ~ 0, and we can't
get the EXP of tmp.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@3678 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r-- | erfc.c | 16 |
1 files changed, 11 insertions, 5 deletions
@@ -52,20 +52,26 @@ mpfr_erfc (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd) } /* Init stuff */ - MPFR_SAVE_EXPO_MARK (expo); + MPFR_SAVE_EXPO_MARK (expo); prec = MPFR_PREC (y) + MPFR_INT_CEIL_LOG2 (MPFR_PREC (y)) + 3; mpfr_init2 (tmp, prec); MPFR_ZIV_INIT (loop, prec); /* Initialize the ZivLoop controler */ for (;;) /* Infinite loop */ { - mpfr_erf (tmp, x, GMP_RNDN); + mpfr_erf (tmp, x, GMP_RNDN); + MPFR_ASSERTD (!MPFR_IS_SINGULAR (tmp)); /* FIXME: 0 only for x=0 ? */ te = MPFR_GET_EXP (tmp); mpfr_ui_sub (tmp, 1, tmp, GMP_RNDN); /* See error analysis of expm1 for details */ - err = prec - (MAX (te - MPFR_GET_EXP (tmp), 0) + 1); - if (MPFR_LIKELY (MPFR_CAN_ROUND (tmp, err, MPFR_PREC (y), rnd))) - break; + if (MPFR_IS_ZERO (tmp)) + prec *=2; + else + { + err = prec - (MAX (te - MPFR_GET_EXP (tmp), 0) + 1); + if (MPFR_LIKELY (MPFR_CAN_ROUND (tmp, err, MPFR_PREC (y), rnd))) + break; + } MPFR_ZIV_NEXT (loop, prec); /* Increase used precision */ mpfr_set_prec (tmp, prec); } |