]> granicus.if.org Git - python/commitdiff
Issue #15477: Add workaround for log1p(-0.0) on platforms where it's broken.
authorMark Dickinson <mdickinson@enthought.com>
Sat, 18 Aug 2012 11:24:30 +0000 (12:24 +0100)
committerMark Dickinson <mdickinson@enthought.com>
Sat, 18 Aug 2012 11:24:30 +0000 (12:24 +0100)
Lib/test/test_cmath.py
Misc/NEWS
Modules/_math.c
Modules/_math.h

index 4e93be47add653f47bcf3bde80507f7669142c47..692ea361f44f942b099ad06a8c420e9a594e923b 100644 (file)
@@ -519,15 +519,11 @@ class CMathTests(unittest.TestCase):
     # of zero, then atan and atanh will also have difficulties with
     # the sign of complex zeros.
     @requires_IEEE_754
-    @unittest.skipIf(sysconfig.get_config_var('LOG1P_DROPS_ZERO_SIGN'),
-                     "system log1p() function doesn't preserve the sign")
     def testAtanSign(self):
         for z in complex_zeros:
             self.assertComplexIdentical(cmath.atan(z), z)
 
     @requires_IEEE_754
-    @unittest.skipIf(sysconfig.get_config_var('LOG1P_DROPS_ZERO_SIGN'),
-                     "system log1p() function doesn't preserve the sign")
     def testAtanhSign(self):
         for z in complex_zeros:
             self.assertComplexIdentical(cmath.atanh(z), z)
index 4f3fc5103f29c9e3d0bf7655d1f344f226a16bf0..8fdd51534c2cae961997d51a8289fc27dec89337 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -104,6 +104,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #15477: In cmath and math modules, add workaround for platforms whose
+  system-supplied log1p function doesn't respect signs of zeros.
+
 - Issue #11062: Fix adding a message from file to Babyl mailbox.
 
 - Issue #15646: Prevent equivalent of a fork bomb when using
index 2fef48107f1ac76aef05944f64a331dc2d01ec45..fe75a36ec5171ea78364cd2e265b849af4c228ae 100644 (file)
@@ -189,6 +189,27 @@ _Py_expm1(double x)
    significant loss of precision that arises from direct evaluation when x is
    small. */
 
+#ifdef HAVE_LOG1P
+
+double
+_Py_log1p(double x)
+{
+    /* Some platforms supply a log1p function but don't respect the sign of
+       zero:  log1p(-0.0) gives 0.0 instead of the correct result of -0.0.
+
+       To save fiddling with configure tests and platform checks, we handle the
+       special case of zero input directly on all platforms.
+    */
+    if (x == 0.0) {
+        return x;
+    }
+    else {
+        return log1p(x);
+    }
+}
+
+#else
+
 double
 _Py_log1p(double x)
 {
@@ -230,3 +251,5 @@ _Py_log1p(double x)
         return log(1.+x);
     }
 }
+
+#endif /* ifdef HAVE_LOG1P */
index c0ceece662600990ffd5a520efbb8f3c80efecce..cf079ad770dc27669212a865c3f231ddd233b73c 100644 (file)
@@ -36,10 +36,6 @@ double _Py_log1p(double x);
 #define m_expm1 _Py_expm1
 #endif
 
-#ifdef HAVE_LOG1P
-#define m_log1p log1p
-#else
-/* if the system doesn't have log1p, use the substitute
-   function defined in Modules/_math.c. */
+/* Use the substitute from _math.c on all platforms:
+   it includes workarounds for buggy handling of zeros. */
 #define m_log1p _Py_log1p
-#endif