[Python-checkins] cpython: Issue #28256: Cleanup _math.c

victor.stinner python-checkins at python.org
Tue Oct 18 10:32:49 EDT 2016


https://hg.python.org/cpython/rev/8999d702ac29
changeset:   104536:8999d702ac29
parent:      104534:69523a2327ec
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Tue Oct 18 16:29:27 2016 +0200
summary:
  Issue #28256: Cleanup _math.c

Only define fallback implementations when needed. It avoids producing deadcode
when the system provides required math functions.

files:
  Modules/_math.c |  49 +++++++++++++++++++++---------------
  Modules/_math.h |  24 +++++++++---------
  2 files changed, 41 insertions(+), 32 deletions(-)


diff --git a/Modules/_math.c b/Modules/_math.c
--- a/Modules/_math.c
+++ b/Modules/_math.c
@@ -19,13 +19,19 @@
  * ====================================================
  */
 
+#if !defined(HAVE_ACOSH) || !defined(HAVE_ASINH)
 static const double ln2 = 6.93147180559945286227E-01;
+static const double two_pow_p28 = 268435456.0; /* 2**28 */
+#endif
+#if !defined(HAVE_ASINH) || !defined(HAVE_ATANH)
 static const double two_pow_m28 = 3.7252902984619141E-09; /* 2**-28 */
-static const double two_pow_p28 = 268435456.0; /* 2**28 */
-#ifndef Py_NAN
+#endif
+#if !defined(HAVE_ATANH) && !defined(Py_NAN)
 static const double zero = 0.0;
 #endif
 
+
+#ifndef HAVE_ACOSH
 /* acosh(x)
  * Method :
  *      Based on
@@ -59,23 +65,25 @@
             return x+x;
         }
         else {
-            return log(x)+ln2;          /* acosh(huge)=log(2x) */
+            return log(x) + ln2;          /* acosh(huge)=log(2x) */
         }
     }
     else if (x == 1.) {
         return 0.0;                     /* acosh(1) = 0 */
     }
     else if (x > 2.) {                  /* 2 < x < 2**28 */
-        double t = x*x;
-        return log(2.0*x - 1.0 / (x + sqrt(t - 1.0)));
+        double t = x * x;
+        return log(2.0 * x - 1.0 / (x + sqrt(t - 1.0)));
     }
     else {                              /* 1 < x <= 2 */
         double t = x - 1.0;
-        return m_log1p(t + sqrt(2.0*t + t*t));
+        return m_log1p(t + sqrt(2.0 * t + t * t));
     }
 }
+#endif   /* HAVE_ACOSH */
 
 
+#ifndef HAVE_ASINH
 /* asinh(x)
  * Method :
  *      Based on
@@ -100,10 +108,10 @@
         return x;                       /* return x inexact except 0 */
     }
     if (absx > two_pow_p28) {           /* |x| > 2**28 */
-        w = log(absx)+ln2;
+        w = log(absx) + ln2;
     }
     else if (absx > 2.0) {              /* 2 < |x| < 2**28 */
-        w = log(2.0*absx + 1.0 / (sqrt(x*x + 1.0) + absx));
+        w = log(2.0 * absx + 1.0 / (sqrt(x * x + 1.0) + absx));
     }
     else {                              /* 2**-28 <= |x| < 2= */
         double t = x*x;
@@ -112,7 +120,10 @@
     return copysign(w, x);
 
 }
+#endif   /* HAVE_ASINH */
 
+
+#ifndef HAVE_ATANH
 /* atanh(x)
  * Method :
  *    1.Reduced x to positive by atanh(-x) = -atanh(x)
@@ -145,7 +156,7 @@
 #ifdef Py_NAN
         return Py_NAN;
 #else
-        return x/zero;
+        return x / zero;
 #endif
     }
     if (absx < two_pow_m28) {           /* |x| < 2**-28 */
@@ -160,7 +171,10 @@
     }
     return copysign(t, x);
 }
+#endif   /* HAVE_ATANH */
 
+
+#ifndef HAVE_EXPM1
 /* Mathematically, expm1(x) = exp(x) - 1.  The expm1 function is designed
    to avoid the significant loss of precision that arises from direct
    evaluation of the expression exp(x) - 1, for x near 0. */
@@ -186,16 +200,17 @@
     else
         return exp(x) - 1.0;
 }
+#endif   /* HAVE_EXPM1 */
+
 
 /* log1p(x) = log(1+x).  The log1p function is designed to avoid the
    significant loss of precision that arises from direct evaluation when x is
    small. */
 
-#ifdef HAVE_LOG1P
-
 double
 _Py_log1p(double x)
 {
+#ifdef HAVE_LOG1P
     /* 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.
 
@@ -208,13 +223,7 @@
     else {
         return log1p(x);
     }
-}
-
 #else
-
-double
-_Py_log1p(double x)
-{
     /* For x small, we use the following approach.  Let y be the nearest float
        to 1+x, then
 
@@ -236,7 +245,7 @@
     */
 
     double y;
-    if (fabs(x) < DBL_EPSILON/2.) {
+    if (fabs(x) < DBL_EPSILON / 2.) {
         return x;
     }
     else if (-0.5 <= x && x <= 1.) {
@@ -246,12 +255,12 @@
            happens, then results from log1p will be inaccurate
            for small x. */
         y = 1.+x;
-        return log(y)-((y-1.)-x)/y;
+        return log(y) - ((y - 1.) - x) / y;
     }
     else {
         /* NaNs and infinities should end up here */
         return log(1.+x);
     }
+#endif /* ifdef HAVE_LOG1P */
 }
 
-#endif /* ifdef HAVE_LOG1P */
diff --git a/Modules/_math.h b/Modules/_math.h
--- a/Modules/_math.h
+++ b/Modules/_math.h
@@ -1,41 +1,41 @@
-double _Py_acosh(double x);
-double _Py_asinh(double x);
-double _Py_atanh(double x);
-double _Py_expm1(double x);
-double _Py_log1p(double x);
-
 #ifdef HAVE_ACOSH
-#define m_acosh acosh
+#  define m_acosh acosh
 #else
 /* if the system doesn't have acosh, use the substitute
    function defined in Modules/_math.c. */
-#define m_acosh _Py_acosh
+double _Py_acosh(double x);
+#  define m_acosh _Py_acosh
 #endif
 
 #ifdef HAVE_ASINH
-#define m_asinh asinh
+#  define m_asinh asinh
 #else
 /* if the system doesn't have asinh, use the substitute
    function defined in Modules/_math.c. */
-#define m_asinh _Py_asinh
+double _Py_asinh(double x);
+#  define m_asinh _Py_asinh
 #endif
 
 #ifdef HAVE_ATANH
-#define m_atanh atanh
+#  define m_atanh atanh
 #else
 /* if the system doesn't have atanh, use the substitute
    function defined in Modules/_math.c. */
+double _Py_atanh(double x);
 #define m_atanh _Py_atanh
 #endif
 
 #ifdef HAVE_EXPM1
-#define m_expm1 expm1
+#  define m_expm1 expm1
 #else
 /* if the system doesn't have expm1, use the substitute
    function defined in Modules/_math.c. */
+double _Py_expm1(double x);
 #define m_expm1 _Py_expm1
 #endif
 
+double _Py_log1p(double x);
+
 /* Use the substitute from _math.c on all platforms:
    it includes workarounds for buggy handling of zeros. */
 #define m_log1p _Py_log1p

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list