summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2006-11-14 16:42:46 +0000
committerzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2006-11-14 16:42:46 +0000
commit1bc6747c6e61be9d423865fdd99be48e48f36233 (patch)
treec7fde610e558a54e298b81f7a24ec2faebef2363
parentb04dfe4232683ec260e869ff63679a6ca7811f6b (diff)
downloadmpfr-1bc6747c6e61be9d423865fdd99be48e48f36233.tar.gz
fixed problem for large negative input
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@4216 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r--erfc.c15
-rw-r--r--tests/terf.c4
2 files changed, 12 insertions, 7 deletions
diff --git a/erfc.c b/erfc.c
index 65a5983b0..0a01e3420 100644
--- a/erfc.c
+++ b/erfc.c
@@ -70,12 +70,12 @@ mpfr_erfc (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd)
}
}
- /* for x < 0, erfc(x) tends to 2 by below */
if (MPFR_SIGN (x) < 0)
{
- if ((MPFR_PREC(y) <= 8 && mpfr_cmp_si (x, -2)) ||
- (MPFR_PREC(y) <= 26 && mpfr_cmp_si (x, -4)) ||
- (MPFR_PREC(y) <= 97 && mpfr_cmp_si (x, -9)))
+ /* for x < 0 going to -infinity, erfc(x) tends to 2 by below */
+ if ((MPFR_PREC(y) <= 7 && mpfr_cmp_si (x, -2) <= 0) ||
+ (MPFR_PREC(y) <= 25 && mpfr_cmp_si (x, -4) <= 0) ||
+ (MPFR_PREC(y) <= 120 && mpfr_cmp_si (x, -9)))
{
mpfr_set_ui (y, 2, GMP_RNDN);
mpfr_set_inexflag ();
@@ -91,6 +91,12 @@ mpfr_erfc (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd)
/* Init stuff */
MPFR_SAVE_EXPO_MARK (expo);
+
+ /* erfc(x) ~ 1, with error < 2^(EXP(x)+1) */
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, __gmpfr_one, 0-MPFR_GET_EXP (x)-1,
+ MPFR_SIGN(x) < 0,
+ rnd, inex = _inexact; goto end);
+
prec = MPFR_PREC (y) + MPFR_INT_CEIL_LOG2 (MPFR_PREC (y)) + 3;
mpfr_init2 (tmp, prec);
@@ -118,6 +124,7 @@ mpfr_erfc (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd)
inex = mpfr_set (y, tmp, rnd); /* Set y to the computed value */
mpfr_clear (tmp);
+ end:
MPFR_SAVE_EXPO_FREE (expo);
return mpfr_check_range (y, inex, rnd);
}
diff --git a/tests/terf.c b/tests/terf.c
index 6bceed4e6..544a9499a 100644
--- a/tests/terf.c
+++ b/tests/terf.c
@@ -400,9 +400,7 @@ main (int argc, char *argv[])
special_erf ();
special_erfc ();
-
- if (argc > 1)
- large_arg ();
+ large_arg ();
test_generic_erf (2, 100, 15);
test_generic_erfc (2, 100, 15);