diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2016-10-18 14:29:27 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2016-10-18 14:29:27 (GMT) |
commit | bf9655854bec3e4cddc0580e815938f9f678cd23 (patch) | |
tree | 6d4944086988d7d968e1555a639aba882025e0fd /Modules | |
parent | 22e36afc17b70fe8171024948b615463380e8484 (diff) | |
download | cpython-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.c | 49 | ||||
-rw-r--r-- | Modules/_math.h | 24 |
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 |