summaryrefslogtreecommitdiff
path: root/erfc.c
diff options
context:
space:
mode:
authorzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2006-10-26 17:17:01 +0000
committerzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2006-10-26 17:17:01 +0000
commit5725cb8555fe33289e602744ca074336affb9a58 (patch)
treed4d900af98f7c0528d794810878bc22b53ee4d8b /erfc.c
parent824cb9fd299f18e85d5b94102f2ab16bc562f36e (diff)
downloadmpfr-5725cb8555fe33289e602744ca074336affb9a58.tar.gz
added tests for overflows or underflows
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@4167 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'erfc.c')
-rw-r--r--erfc.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/erfc.c b/erfc.c
index e71287ecd..4c0197e67 100644
--- a/erfc.c
+++ b/erfc.c
@@ -19,6 +19,7 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301, USA. */
+#include <stdlib.h>
#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
@@ -51,6 +52,37 @@ mpfr_erfc (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd)
return mpfr_set_ui (y, 1, rnd);
}
+ if (MPFR_SIGN (x) > 0)
+ {
+ /* for x >= 38582, erfc(x) < 2^(-2^31) */
+ if (mpfr_cmp_ui (x, 38582) >= 0)
+ return mpfr_underflow (y, (rnd == GMP_RNDN) ? GMP_RNDZ : rnd, 1);
+ if (MPFR_GET_EXP (x) >= 12)
+ {
+ fprintf (stderr, "MPFR: Error, too large input in mpfr_erfc\n");
+ abort ();
+ }
+ }
+
+ /* 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)))
+ {
+ mpfr_set_ui (y, 2, GMP_RNDN);
+ mpfr_set_inexflag ();
+ if (rnd == GMP_RNDZ || rnd == GMP_RNDD)
+ {
+ mpfr_nextbelow (y);
+ return -1;
+ }
+ else
+ return 1;
+ }
+ }
+
/* Init stuff */
MPFR_SAVE_EXPO_MARK (expo);
prec = MPFR_PREC (y) + MPFR_INT_CEIL_LOG2 (MPFR_PREC (y)) + 3;