mirror of https://github.com/python/cpython
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.
This commit is contained in:
parent
8842c356aa
commit
e979ec8fbf
|
@ -84,6 +84,25 @@ erf0041 erf 1e16 -> 1.0
|
||||||
erf0042 erf -1e150 -> -1.0
|
erf0042 erf -1e150 -> -1.0
|
||||||
erf0043 erf 1.7e308 -> 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 --
|
-- erfc: complementary error function --
|
||||||
|
@ -127,6 +146,25 @@ erfc0051 erfc 1e16 -> 0.0
|
||||||
erfc0052 erfc -1e150 -> 2.0
|
erfc0052 erfc -1e150 -> 2.0
|
||||||
erfc0053 erfc 1.7e308 -> 0.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 --
|
-- lgamma: log of absolute value of the gamma function --
|
||||||
|
|
|
@ -996,6 +996,15 @@ class MathTests(unittest.TestCase):
|
||||||
accuracy_failure = acc_check(expected, got,
|
accuracy_failure = acc_check(expected, got,
|
||||||
rel_err = 5e-15,
|
rel_err = 5e-15,
|
||||||
abs_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:
|
else:
|
||||||
accuracy_failure = ulps_check(expected, got, 20)
|
accuracy_failure = ulps_check(expected, got, 20)
|
||||||
if accuracy_failure is None:
|
if accuracy_failure is None:
|
||||||
|
|
|
@ -151,6 +151,7 @@ Benjamin Collar
|
||||||
Jeffery Collins
|
Jeffery Collins
|
||||||
Robert Collins
|
Robert Collins
|
||||||
Paul Colomiets
|
Paul Colomiets
|
||||||
|
Geremy Condra
|
||||||
Juan José Conti
|
Juan José Conti
|
||||||
Matt Conway
|
Matt Conway
|
||||||
David M. Cooke
|
David M. Cooke
|
||||||
|
|
|
@ -25,6 +25,10 @@ Core and Builtins
|
||||||
|
|
||||||
Library
|
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 #8924: logging: Improved error handling for Unicode in exception text.
|
||||||
|
|
||||||
- Issue #8948: cleanup functions and class / module setups and teardowns are
|
- Issue #8948: cleanup functions and class / module setups and teardowns are
|
||||||
|
|
|
@ -428,8 +428,8 @@ m_lgamma(double x)
|
||||||
static double
|
static double
|
||||||
m_erf_series(double x)
|
m_erf_series(double x)
|
||||||
{
|
{
|
||||||
double x2, acc, fk;
|
double x2, acc, fk, result;
|
||||||
int i;
|
int i, saved_errno;
|
||||||
|
|
||||||
x2 = x * x;
|
x2 = x * x;
|
||||||
acc = 0.0;
|
acc = 0.0;
|
||||||
|
@ -438,7 +438,12 @@ m_erf_series(double x)
|
||||||
acc = 2.0 + x2 * acc / fk;
|
acc = 2.0 + x2 * acc / fk;
|
||||||
fk -= 1.0;
|
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
|
static double
|
||||||
m_erfc_contfrac(double x)
|
m_erfc_contfrac(double x)
|
||||||
{
|
{
|
||||||
double x2, a, da, p, p_last, q, q_last, b;
|
double x2, a, da, p, p_last, q, q_last, b, result;
|
||||||
int i;
|
int i, saved_errno;
|
||||||
|
|
||||||
if (x >= ERFC_CONTFRAC_CUTOFF)
|
if (x >= ERFC_CONTFRAC_CUTOFF)
|
||||||
return 0.0;
|
return 0.0;
|
||||||
|
@ -472,7 +477,12 @@ m_erfc_contfrac(double x)
|
||||||
temp = p; p = b*p - a*p_last; p_last = temp;
|
temp = p; p = b*p - a*p_last; p_last = temp;
|
||||||
temp = q; q = b*q - a*q_last; q_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 */
|
/* Error function erf(x), for general x */
|
||||||
|
|
Loading…
Reference in New Issue