summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2016-10-18 14:29:27 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2016-10-18 14:29:27 (GMT)
commitbf9655854bec3e4cddc0580e815938f9f678cd23 (patch)
tree6d4944086988d7d968e1555a639aba882025e0fd /Modules
parent22e36afc17b70fe8171024948b615463380e8484 (diff)
downloadcpython-bf9655854bec3e4cddc0580e815938f9f678cd23.zip
cpython-bf9655854bec3e4cddc0580e815938f9f678cd23.tar.gz
cpython-bf9655854bec3e4cddc0580e815938f9f678cd23.tar.bz2
Issue #28256: Cleanup _math.c
Only define fallback implementations when needed. It avoids producing deadcode when the system provides required math functions.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_math.c49
-rw-r--r--Modules/_math.h24
2 files changed, 41 insertions, 32 deletions
diff --git a/Modules/_math.c b/Modules/_math.c
index a002208..02d8f1c 100644
--- 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_m28 = 3.7252902984619141E-09; /* 2**-28 */
static const double two_pow_p28 = 268435456.0; /* 2**28 */
-#ifndef Py_NAN
+#endif
+#if !defined(HAVE_ASINH) || !defined(HAVE_ATANH)
+static const double two_pow_m28 = 3.7252902984619141E-09; /* 2**-28 */
+#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 @@ _Py_acosh(double x)
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 @@ _Py_asinh(double x)
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 @@ _Py_asinh(double x)
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 @@ _Py_atanh(double x)
#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 @@ _Py_atanh(double x)
}
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 @@ _Py_expm1(double x)
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 @@ _Py_log1p(double x)
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 @@ _Py_log1p(double x)
*/
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 @@ _Py_log1p(double x)
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
index cf079ad..398b7e8 100644
--- 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