summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Dickinson <dickinsm@gmail.com>2010-06-13 10:52:38 (GMT)
committerMark Dickinson <dickinsm@gmail.com>2010-06-13 10:52:38 (GMT)
commitbcdf9da26581266a35a2c7adc835c4580177c1ec (patch)
tree8223c5a8f1faa149c69305f68e97c463c1369a19
parentc6f1396be0a09d44de4ea8415c72c947521229d7 (diff)
downloadcpython-bcdf9da26581266a35a2c7adc835c4580177c1ec.zip
cpython-bcdf9da26581266a35a2c7adc835c4580177c1ec.tar.gz
cpython-bcdf9da26581266a35a2c7adc835c4580177c1ec.tar.bz2
Merged revisions 81967 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r81967 | mark.dickinson | 2010-06-13 11:50:29 +0100 (Sun, 13 Jun 2010) | 4 lines Issue #8986: erfc was raising OverflowError on Linux for arguments in the (approximate) range (-27.3, 30.0), as a result of an escaped errno value. ........
-rw-r--r--Lib/test/math_testcases.txt38
-rw-r--r--Lib/test/test_math.py9
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS3
-rw-r--r--Modules/mathmodule.c22
5 files changed, 67 insertions, 6 deletions
diff --git a/Lib/test/math_testcases.txt b/Lib/test/math_testcases.txt
index 21730df..be1a49f 100644
--- a/Lib/test/math_testcases.txt
+++ b/Lib/test/math_testcases.txt
@@ -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 --
diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py
index 6c44435..6c07c88 100644
--- a/Lib/test/test_math.py
+++ b/Lib/test/test_math.py
@@ -1042,6 +1042,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:
diff --git a/Misc/ACKS b/Misc/ACKS
index 7f97de6..9795219 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -153,6 +153,7 @@ Benjamin Collar
Jeffery Collins
Robert Collins
Paul Colomiets
+Geremy Condra
Juan José Conti
Matt Conway
David M. Cooke
diff --git a/Misc/NEWS b/Misc/NEWS
index a5e0164..65ab474 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -428,6 +428,9 @@ C-API
Library
-------
+- Issue #8986: math.erfc was incorrectly raising OverflowError for
+ values between -27.3 and -30.0 on some platforms.
+
- Issue #8784: Set tarfile default encoding to 'utf-8' on Windows.
- Issue #8966: If a ctypes structure field is an array of c_char, convert its
diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c
index d57ad90..bc3f5dd 100644
--- a/Modules/mathmodule.c
+++ b/Modules/mathmodule.c
@@ -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 */