diff Modules/mathmodule.c @ 62317:d064e8934f4d

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. ........
author Mark Dickinson <dickinsm@gmail.com>
date Sun, 13 Jun 2010 10:52:38 +0000
parents 1e149b50aca6
children 1c5c146de642
line wrap: on
line diff
--- a/Modules/mathmodule.c	Sun Jun 13 09:17:13 2010 +0000
+++ b/Modules/mathmodule.c	Sun Jun 13 10:52:38 2010 +0000
@@ -428,8 +428,8 @@
 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 @@
         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 @@
 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 @@
         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 */