diff -r 3fba718e46e5 Lib/test/test_cmath.py --- a/Lib/test/test_cmath.py Sat Aug 18 09:50:32 2012 +0300 +++ b/Lib/test/test_cmath.py Sat Aug 18 10:20:25 2012 +0100 @@ -519,15 +519,11 @@ # 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) diff -r 3fba718e46e5 Modules/_math.c --- a/Modules/_math.c Sat Aug 18 09:50:32 2012 +0300 +++ b/Modules/_math.c Sat Aug 18 10:20:25 2012 +0100 @@ -189,6 +189,27 @@ 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 @@ return log(1.+x); } } + +#endif /* ifdef HAVE_LOG1P */ diff -r 3fba718e46e5 Modules/_math.h --- a/Modules/_math.h Sat Aug 18 09:50:32 2012 +0300 +++ b/Modules/_math.h Sat Aug 18 10:20:25 2012 +0100 @@ -36,10 +36,6 @@ #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