aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Dickinson <dickinsm@gmail.com>2009-12-16 20:23:42 +0000
committerMark Dickinson <dickinsm@gmail.com>2009-12-16 20:23:42 +0000
commit664b511c0acdfdecdec92d2255ffd94c4e6d5f7a (patch)
tree075cdf8651d66f24e42c1b87e57e7423e3e7a9d3 /Modules/_math.c
parentMerged revisions 76856 via svnmerge from (diff)
downloadcpython-664b511c0acdfdecdec92d2255ffd94c4e6d5f7a.tar.gz
cpython-664b511c0acdfdecdec92d2255ffd94c4e6d5f7a.tar.bz2
cpython-664b511c0acdfdecdec92d2255ffd94c4e6d5f7a.zip
Merged revisions 76861 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r76861 | mark.dickinson | 2009-12-16 20:13:40 +0000 (Wed, 16 Dec 2009) | 3 lines Issue #3366: Add expm1 function to math module. Thanks Eric Smith for testing on Windows. ........
Diffstat (limited to 'Modules/_math.c')
-rw-r--r--Modules/_math.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/Modules/_math.c b/Modules/_math.c
new file mode 100644
index 00000000000..9d330aa0d59
--- /dev/null
+++ b/Modules/_math.c
@@ -0,0 +1,31 @@
+/* Definitions of some C99 math library functions, for those platforms
+ that don't implement these functions already. */
+
+#include <float.h>
+#include <math.h>
+
+/* 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. */
+
+double
+_Py_expm1(double x)
+{
+ /* For abs(x) >= log(2), it's safe to evaluate exp(x) - 1 directly; this
+ also works fine for infinities and nans.
+
+ For smaller x, we can use a method due to Kahan that achieves close to
+ full accuracy.
+ */
+
+ if (fabs(x) < 0.7) {
+ double u;
+ u = exp(x);
+ if (u == 1.0)
+ return x;
+ else
+ return (u - 1.0) * x / log(u);
+ }
+ else
+ return exp(x) - 1.0;
+}