]> granicus.if.org Git - python/commitdiff
Issue #8986: erfc was raising OverflowError on Linux for arguments in
authorMark Dickinson <dickinsm@gmail.com>
Sun, 13 Jun 2010 10:50:29 +0000 (10:50 +0000)
committerMark Dickinson <dickinsm@gmail.com>
Sun, 13 Jun 2010 10:50:29 +0000 (10:50 +0000)
the (approximate) range (-27.3, 30.0), as a result of an escaped errno
value.

Lib/test/math_testcases.txt
Lib/test/test_math.py
Misc/ACKS
Misc/NEWS
Modules/mathmodule.c

index 21730df720911f1b7139ad59f9591415052bdac2..be1a49f0d360b90da3a53a5adbd49014919d8b96 100644 (file)
@@ -84,6 +84,25 @@ erf0041 erf 1e16 -> 1.0
 erf0042 erf -1e150 -> -1.0
 erf0043 erf 1.7e308 -> 1.0
 
+-- Issue 8986: inputs x with exp(-x*x) near the underflow threshold
+-- incorrectly signalled overflow on some platforms.
+erf0100 erf 26.2 -> 1.0
+erf0101 erf 26.4 -> 1.0
+erf0102 erf 26.6 -> 1.0
+erf0103 erf 26.8 -> 1.0
+erf0104 erf 27.0 -> 1.0
+erf0105 erf 27.2 -> 1.0
+erf0106 erf 27.4 -> 1.0
+erf0107 erf 27.6 -> 1.0
+
+erf0110 erf -26.2 -> -1.0
+erf0111 erf -26.4 -> -1.0
+erf0112 erf -26.6 -> -1.0
+erf0113 erf -26.8 -> -1.0
+erf0114 erf -27.0 -> -1.0
+erf0115 erf -27.2 -> -1.0
+erf0116 erf -27.4 -> -1.0
+erf0117 erf -27.6 -> -1.0
 
 ----------------------------------------
 -- erfc: complementary error function --
@@ -127,6 +146,25 @@ erfc0051 erfc 1e16 -> 0.0
 erfc0052 erfc -1e150 -> 2.0
 erfc0053 erfc 1.7e308 -> 0.0
 
+-- Issue 8986: inputs x with exp(-x*x) near the underflow threshold
+-- incorrectly signalled overflow on some platforms.
+erfc0100 erfc 26.2 -> 1.6432507924389461e-300
+erfc0101 erfc 26.4 -> 4.4017768588035426e-305
+erfc0102 erfc 26.6 -> 1.0885125885442269e-309
+erfc0103 erfc 26.8 -> 2.4849621571966629e-314
+erfc0104 erfc 27.0 -> 5.2370464393526292e-319
+erfc0105 erfc 27.2 -> 9.8813129168249309e-324
+erfc0106 erfc 27.4 -> 0.0
+erfc0107 erfc 27.6 -> 0.0
+
+erfc0110 erfc -26.2 -> 2.0
+erfc0111 erfc -26.4 -> 2.0
+erfc0112 erfc -26.6 -> 2.0
+erfc0113 erfc -26.8 -> 2.0
+erfc0114 erfc -27.0 -> 2.0
+erfc0115 erfc -27.2 -> 2.0
+erfc0116 erfc -27.4 -> 2.0
+erfc0117 erfc -27.6 -> 2.0
 
 ---------------------------------------------------------
 -- lgamma: log of absolute value of the gamma function --
index 36f68479073bb2ef6ffd9cd02c5be8e15ede41f9..3049ef1f47284eedec18d3cca49222ed090a48b9 100644 (file)
@@ -996,6 +996,15 @@ class MathTests(unittest.TestCase):
                         accuracy_failure = acc_check(expected, got,
                                                   rel_err = 5e-15,
                                                   abs_err = 5e-15)
+                    elif fn == 'erfc':
+                        # erfc has less-than-ideal accuracy for large
+                        # arguments (x ~ 25 or so), mainly due to the
+                        # error involved in computing exp(-x*x).
+                        #
+                        # XXX Would be better to weaken this test only
+                        # for large x, instead of for all x.
+                        accuracy_failure = ulps_check(expected, got, 2000)
+
                     else:
                         accuracy_failure = ulps_check(expected, got, 20)
                     if accuracy_failure is None:
index c798ebb891db7603d73a5c5b5d9305062b7f7732..01957c27f0d5578fcaacbdb508e354a4cb691d3b 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -151,6 +151,7 @@ Benjamin Collar
 Jeffery Collins
 Robert Collins
 Paul Colomiets
+Geremy Condra
 Juan José Conti
 Matt Conway
 David M. Cooke
index 891a3e9c32e2b496f23f43c3969f2678ba8acae7..152725aaa3e2cee9b003f2e40ea50fd27d6592b4 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -25,6 +25,10 @@ Core and Builtins
 
 Library
 -------
+
+- Issue #8986: math.erfc was incorrectly raising OverflowError for
+  values between -27.3 and -30.0 on some platforms.
+
 - Issue #8924: logging: Improved error handling for Unicode in exception text.
 
 - Issue #8948: cleanup functions and class / module setups and teardowns are
index 77b56a0027fcfd60e6b2e7a2c595f716e65d0d70..b3b80f4787e460eb0e7fbfb7c01a59a043d80a12 100644 (file)
@@ -428,8 +428,8 @@ m_lgamma(double x)
 static double
 m_erf_series(double x)
 {
-    double x2, acc, fk;
-    int i;
+    double x2, acc, fk, result;
+    int i, saved_errno;
 
     x2 = x * x;
     acc = 0.0;
@@ -438,7 +438,12 @@ m_erf_series(double x)
         acc = 2.0 + x2 * acc / fk;
         fk -= 1.0;
     }
-    return acc * x * exp(-x2) / sqrtpi;
+    /* Make sure the exp call doesn't affect errno;
+       see m_erfc_contfrac for more. */
+    saved_errno = errno;
+    result = acc * x * exp(-x2) / sqrtpi;
+    errno = saved_errno;
+    return result;
 }
 
 /*
@@ -453,8 +458,8 @@ m_erf_series(double x)
 static double
 m_erfc_contfrac(double x)
 {
-    double x2, a, da, p, p_last, q, q_last, b;
-    int i;
+    double x2, a, da, p, p_last, q, q_last, b, result;
+    int i, saved_errno;
 
     if (x >= ERFC_CONTFRAC_CUTOFF)
         return 0.0;
@@ -472,7 +477,12 @@ m_erfc_contfrac(double x)
         temp = p; p = b*p - a*p_last; p_last = temp;
         temp = q; q = b*q - a*q_last; q_last = temp;
     }
-    return p / q * x * exp(-x2) / sqrtpi;
+    /* Issue #8986: On some platforms, exp sets errno on underflow to zero;
+       save the current errno value so that we can restore it later. */
+    saved_errno = errno;
+    result = p / q * x * exp(-x2) / sqrtpi;
+    errno = saved_errno;
+    return result;
 }
 
 /* Error function erf(x), for general x */