annotate Modules/mathmodule.c @ 57655:cb22eaee86c9 legacy-trunk

Issue #3366: Add lgamma function to math module.
author Mark Dickinson <dickinsm@gmail.com>
date Fri, 11 Dec 2009 17:29:33 +0000
parents 7e02371aa506
children b206ad8cf5bf
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1 /* Math module -- standard C math library functions, pi and e */
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
3 /* Here are some comments from Tim Peters, extracted from the
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
4 discussion attached to http://bugs.python.org/issue1640. They
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
5 describe the general aims of the math module with respect to
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
6 special values, IEEE-754 floating-point exceptions, and Python
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
7 exceptions.
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
8
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
9 These are the "spirit of 754" rules:
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
10
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
11 1. If the mathematical result is a real number, but of magnitude too
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
12 large to approximate by a machine float, overflow is signaled and the
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
13 result is an infinity (with the appropriate sign).
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
14
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
15 2. If the mathematical result is a real number, but of magnitude too
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
16 small to approximate by a machine float, underflow is signaled and the
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
17 result is a zero (with the appropriate sign).
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
18
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
19 3. At a singularity (a value x such that the limit of f(y) as y
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
20 approaches x exists and is an infinity), "divide by zero" is signaled
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
21 and the result is an infinity (with the appropriate sign). This is
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
22 complicated a little by that the left-side and right-side limits may
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
23 not be the same; e.g., 1/x approaches +inf or -inf as x approaches 0
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
24 from the positive or negative directions. In that specific case, the
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
25 sign of the zero determines the result of 1/0.
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
26
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
27 4. At a point where a function has no defined result in the extended
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
28 reals (i.e., the reals plus an infinity or two), invalid operation is
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
29 signaled and a NaN is returned.
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
30
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
31 And these are what Python has historically /tried/ to do (but not
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
32 always successfully, as platform libm behavior varies a lot):
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
33
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
34 For #1, raise OverflowError.
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
35
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
36 For #2, return a zero (with the appropriate sign if that happens by
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
37 accident ;-)).
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
38
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
39 For #3 and #4, raise ValueError. It may have made sense to raise
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
40 Python's ZeroDivisionError in #3, but historically that's only been
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
41 raised for division by zero and mod by zero.
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
42
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
43 */
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
44
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
45 /*
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
46 In general, on an IEEE-754 platform the aim is to follow the C99
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
47 standard, including Annex 'F', whenever possible. Where the
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
48 standard recommends raising the 'divide-by-zero' or 'invalid'
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
49 floating-point exceptions, Python should raise a ValueError. Where
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
50 the standard recommends raising 'overflow', Python should raise an
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
51 OverflowError. In all other circumstances a value should be
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
52 returned.
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
53 */
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
54
4635
49745ddb4f69 Renamed
Barry Warsaw <barry@python.org>
parents: 4503
diff changeset
55 #include "Python.h"
34872
0143d990d60c Make that a C, not a C++, comment.
Michael W. Hudson <mwh@python.net>
parents: 34871
diff changeset
56 #include "longintrepr.h" /* just for SHIFT */
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
57
44940
12099143724f Add prototypes to get the mathmodule.c to compile on OSF1 5.1 (Tru64)
Neal Norwitz <nnorwitz@gmail.com>
parents: 44488
diff changeset
58 #ifdef _OSF_SOURCE
12099143724f Add prototypes to get the mathmodule.c to compile on OSF1 5.1 (Tru64)
Neal Norwitz <nnorwitz@gmail.com>
parents: 44488
diff changeset
59 /* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */
12099143724f Add prototypes to get the mathmodule.c to compile on OSF1 5.1 (Tru64)
Neal Norwitz <nnorwitz@gmail.com>
parents: 44488
diff changeset
60 extern double copysign(double, double);
12099143724f Add prototypes to get the mathmodule.c to compile on OSF1 5.1 (Tru64)
Neal Norwitz <nnorwitz@gmail.com>
parents: 44488
diff changeset
61 #endif
12099143724f Add prototypes to get the mathmodule.c to compile on OSF1 5.1 (Tru64)
Neal Norwitz <nnorwitz@gmail.com>
parents: 44488
diff changeset
62
56268
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
63 /*
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
64 sin(pi*x), giving accurate results for all finite x (especially x
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
65 integral or close to an integer). This is here for use in the
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
66 reflection formula for the gamma function. It conforms to IEEE
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
67 754-2008 for finite arguments, but not for infinities or nans.
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
68 */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
69
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
70 static const double pi = 3.141592653589793238462643383279502884197;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
71
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
72 static double
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
73 sinpi(double x)
498
56bb1067a880 Improve error handling.
Guido van Rossum <guido@python.org>
parents: 438
diff changeset
74 {
56268
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
75 double y, r;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
76 int n;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
77 /* this function should only ever be called for finite arguments */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
78 assert(Py_IS_FINITE(x));
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
79 y = fmod(fabs(x), 2.0);
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
80 n = (int)round(2.0*y);
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
81 assert(0 <= n && n <= 4);
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
82 switch (n) {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
83 case 0:
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
84 r = sin(pi*y);
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
85 break;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
86 case 1:
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
87 r = cos(pi*(y-0.5));
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
88 break;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
89 case 2:
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
90 /* N.B. -sin(pi*(y-1.0)) is *not* equivalent: it would give
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
91 -0.0 instead of 0.0 when y == 1.0. */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
92 r = sin(pi*(1.0-y));
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
93 break;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
94 case 3:
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
95 r = -cos(pi*(y-1.5));
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
96 break;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
97 case 4:
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
98 r = sin(pi*(y-2.0));
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
99 break;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
100 default:
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
101 assert(0); /* should never get here */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
102 r = -1.23e200; /* silence gcc warning */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
103 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
104 return copysign(1.0, x)*r;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
105 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
106
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
107 /* Implementation of the real gamma function. In extensive but non-exhaustive
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
108 random tests, this function proved accurate to within <= 10 ulps across the
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
109 entire float domain. Note that accuracy may depend on the quality of the
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
110 system math functions, the pow function in particular. Special cases
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
111 follow C99 annex F. The parameters and method are tailored to platforms
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
112 whose double format is the IEEE 754 binary64 format.
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
113
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
114 Method: for x > 0.0 we use the Lanczos approximation with parameters N=13
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
115 and g=6.024680040776729583740234375; these parameters are amongst those
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
116 used by the Boost library. Following Boost (again), we re-express the
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
117 Lanczos sum as a rational function, and compute it that way. The
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
118 coefficients below were computed independently using MPFR, and have been
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
119 double-checked against the coefficients in the Boost source code.
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
120
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
121 For x < 0.0 we use the reflection formula.
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
122
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
123 There's one minor tweak that deserves explanation: Lanczos' formula for
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
124 Gamma(x) involves computing pow(x+g-0.5, x-0.5) / exp(x+g-0.5). For many x
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
125 values, x+g-0.5 can be represented exactly. However, in cases where it
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
126 can't be represented exactly the small error in x+g-0.5 can be magnified
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
127 significantly by the pow and exp calls, especially for large x. A cheap
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
128 correction is to multiply by (1 + e*g/(x+g-0.5)), where e is the error
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
129 involved in the computation of x+g-0.5 (that is, e = computed value of
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
130 x+g-0.5 - exact value of x+g-0.5). Here's the proof:
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
131
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
132 Correction factor
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
133 -----------------
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
134 Write x+g-0.5 = y-e, where y is exactly representable as an IEEE 754
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
135 double, and e is tiny. Then:
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
136
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
137 pow(x+g-0.5,x-0.5)/exp(x+g-0.5) = pow(y-e, x-0.5)/exp(y-e)
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
138 = pow(y, x-0.5)/exp(y) * C,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
139
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
140 where the correction_factor C is given by
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
141
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
142 C = pow(1-e/y, x-0.5) * exp(e)
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
143
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
144 Since e is tiny, pow(1-e/y, x-0.5) ~ 1-(x-0.5)*e/y, and exp(x) ~ 1+e, so:
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
145
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
146 C ~ (1-(x-0.5)*e/y) * (1+e) ~ 1 + e*(y-(x-0.5))/y
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
147
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
148 But y-(x-0.5) = g+e, and g+e ~ g. So we get C ~ 1 + e*g/y, and
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
149
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
150 pow(x+g-0.5,x-0.5)/exp(x+g-0.5) ~ pow(y, x-0.5)/exp(y) * (1 + e*g/y),
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
151
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
152 Note that for accuracy, when computing r*C it's better to do
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
153
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
154 r + e*g/y*r;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
155
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
156 than
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
157
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
158 r * (1 + e*g/y);
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
159
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
160 since the addition in the latter throws away most of the bits of
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
161 information in e*g/y.
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
162 */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
163
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
164 #define LANCZOS_N 13
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
165 static const double lanczos_g = 6.024680040776729583740234375;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
166 static const double lanczos_g_minus_half = 5.524680040776729583740234375;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
167 static const double lanczos_num_coeffs[LANCZOS_N] = {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
168 23531376880.410759688572007674451636754734846804940,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
169 42919803642.649098768957899047001988850926355848959,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
170 35711959237.355668049440185451547166705960488635843,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
171 17921034426.037209699919755754458931112671403265390,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
172 6039542586.3520280050642916443072979210699388420708,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
173 1439720407.3117216736632230727949123939715485786772,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
174 248874557.86205415651146038641322942321632125127801,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
175 31426415.585400194380614231628318205362874684987640,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
176 2876370.6289353724412254090516208496135991145378768,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
177 186056.26539522349504029498971604569928220784236328,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
178 8071.6720023658162106380029022722506138218516325024,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
179 210.82427775157934587250973392071336271166969580291,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
180 2.5066282746310002701649081771338373386264310793408
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
181 };
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
182
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
183 /* denominator is x*(x+1)*...*(x+LANCZOS_N-2) */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
184 static const double lanczos_den_coeffs[LANCZOS_N] = {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
185 0.0, 39916800.0, 120543840.0, 150917976.0, 105258076.0, 45995730.0,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
186 13339535.0, 2637558.0, 357423.0, 32670.0, 1925.0, 66.0, 1.0};
19750
35b6a1d0b1e0 Rework the way we try to check for libm overflow, given that C99 no longer
Tim Peters <tim.peters@gmail.com>
parents: 19730
diff changeset
187
56268
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
188 /* gamma values for small positive integers, 1 though NGAMMA_INTEGRAL */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
189 #define NGAMMA_INTEGRAL 23
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
190 static const double gamma_integral[NGAMMA_INTEGRAL] = {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
191 1.0, 1.0, 2.0, 6.0, 24.0, 120.0, 720.0, 5040.0, 40320.0, 362880.0,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
192 3628800.0, 39916800.0, 479001600.0, 6227020800.0, 87178291200.0,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
193 1307674368000.0, 20922789888000.0, 355687428096000.0,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
194 6402373705728000.0, 121645100408832000.0, 2432902008176640000.0,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
195 51090942171709440000.0, 1124000727777607680000.0,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
196 };
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
197
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
198 /* Lanczos' sum L_g(x), for positive x */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
199
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
200 static double
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
201 lanczos_sum(double x)
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
202 {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
203 double num = 0.0, den = 0.0;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
204 int i;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
205 assert(x > 0.0);
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
206 /* evaluate the rational function lanczos_sum(x). For large
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
207 x, the obvious algorithm risks overflow, so we instead
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
208 rescale the denominator and numerator of the rational
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
209 function by x**(1-LANCZOS_N) and treat this as a
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
210 rational function in 1/x. This also reduces the error for
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
211 larger x values. The choice of cutoff point (5.0 below) is
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
212 somewhat arbitrary; in tests, smaller cutoff values than
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
213 this resulted in lower accuracy. */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
214 if (x < 5.0) {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
215 for (i = LANCZOS_N; --i >= 0; ) {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
216 num = num * x + lanczos_num_coeffs[i];
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
217 den = den * x + lanczos_den_coeffs[i];
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
218 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
219 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
220 else {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
221 for (i = 0; i < LANCZOS_N; i++) {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
222 num = num / x + lanczos_num_coeffs[i];
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
223 den = den / x + lanczos_den_coeffs[i];
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
224 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
225 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
226 return num/den;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
227 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
228
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
229 static double
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
230 m_tgamma(double x)
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
231 {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
232 double absx, r, y, z, sqrtpow;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
233
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
234 /* special cases */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
235 if (!Py_IS_FINITE(x)) {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
236 if (Py_IS_NAN(x) || x > 0.0)
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
237 return x; /* tgamma(nan) = nan, tgamma(inf) = inf */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
238 else {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
239 errno = EDOM;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
240 return Py_NAN; /* tgamma(-inf) = nan, invalid */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
241 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
242 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
243 if (x == 0.0) {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
244 errno = EDOM;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
245 return 1.0/x; /* tgamma(+-0.0) = +-inf, divide-by-zero */
15170
09c7ac188ce2 Stop raising OverflowError on underflows reported by libm (errno==ERANGE and
Tim Peters <tim.peters@gmail.com>
parents: 14616
diff changeset
246 }
56268
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
247
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
248 /* integer arguments */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
249 if (x == floor(x)) {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
250 if (x < 0.0) {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
251 errno = EDOM; /* tgamma(n) = nan, invalid for */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
252 return Py_NAN; /* negative integers n */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
253 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
254 if (x <= NGAMMA_INTEGRAL)
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
255 return gamma_integral[(int)x - 1];
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
256 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
257 absx = fabs(x);
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
258
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
259 /* tiny arguments: tgamma(x) ~ 1/x for x near 0 */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
260 if (absx < 1e-20) {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
261 r = 1.0/x;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
262 if (Py_IS_INFINITY(r))
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
263 errno = ERANGE;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
264 return r;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
265 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
266
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
267 /* large arguments: assuming IEEE 754 doubles, tgamma(x) overflows for
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
268 x > 200, and underflows to +-0.0 for x < -200, not a negative
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
269 integer. */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
270 if (absx > 200.0) {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
271 if (x < 0.0) {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
272 return 0.0/sinpi(x);
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
273 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
274 else {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
275 errno = ERANGE;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
276 return Py_HUGE_VAL;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
277 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
278 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
279
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
280 y = absx + lanczos_g_minus_half;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
281 /* compute error in sum */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
282 if (absx > lanczos_g_minus_half) {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
283 /* note: the correction can be foiled by an optimizing
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
284 compiler that (incorrectly) thinks that an expression like
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
285 a + b - a - b can be optimized to 0.0. This shouldn't
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
286 happen in a standards-conforming compiler. */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
287 double q = y - absx;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
288 z = q - lanczos_g_minus_half;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
289 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
290 else {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
291 double q = y - lanczos_g_minus_half;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
292 z = q - absx;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
293 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
294 z = z * lanczos_g / y;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
295 if (x < 0.0) {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
296 r = -pi / sinpi(absx) / absx * exp(y) / lanczos_sum(absx);
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
297 r -= z * r;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
298 if (absx < 140.0) {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
299 r /= pow(y, absx - 0.5);
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
300 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
301 else {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
302 sqrtpow = pow(y, absx / 2.0 - 0.25);
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
303 r /= sqrtpow;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
304 r /= sqrtpow;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
305 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
306 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
307 else {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
308 r = lanczos_sum(absx) / exp(y);
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
309 r += z * r;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
310 if (absx < 140.0) {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
311 r *= pow(y, absx - 0.5);
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
312 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
313 else {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
314 sqrtpow = pow(y, absx / 2.0 - 0.25);
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
315 r *= sqrtpow;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
316 r *= sqrtpow;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
317 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
318 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
319 if (Py_IS_INFINITY(r))
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
320 errno = ERANGE;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
321 return r;
498
56bb1067a880 Improve error handling.
Guido van Rossum <guido@python.org>
parents: 438
diff changeset
322 }
56bb1067a880 Improve error handling.
Guido van Rossum <guido@python.org>
parents: 438
diff changeset
323
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
324 /*
57655
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
325 lgamma: natural log of the absolute value of the Gamma function.
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
326 For large arguments, Lanczos' formula works extremely well here.
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
327 */
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
328
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
329 static double
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
330 m_lgamma(double x)
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
331 {
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
332 double r, absx;
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
333
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
334 /* special cases */
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
335 if (!Py_IS_FINITE(x)) {
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
336 if (Py_IS_NAN(x))
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
337 return x; /* lgamma(nan) = nan */
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
338 else
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
339 return Py_HUGE_VAL; /* lgamma(+-inf) = +inf */
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
340 }
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
341
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
342 /* integer arguments */
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
343 if (x == floor(x) && x <= 2.0) {
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
344 if (x <= 0.0) {
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
345 errno = EDOM; /* lgamma(n) = inf, divide-by-zero for */
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
346 return Py_HUGE_VAL; /* integers n <= 0 */
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
347 }
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
348 else {
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
349 return 0.0; /* lgamma(1) = lgamma(2) = 0.0 */
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
350 }
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
351 }
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
352
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
353 absx = fabs(x);
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
354 /* tiny arguments: lgamma(x) ~ -log(fabs(x)) for small x */
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
355 if (absx < 1e-20)
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
356 return -log(absx);
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
357
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
358 /* Lanczos' formula */
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
359 if (x > 0.0) {
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
360 /* we could save a fraction of a ulp in accuracy by having a
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
361 second set of numerator coefficients for lanczos_sum that
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
362 absorbed the exp(-lanczos_g) term, and throwing out the
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
363 lanczos_g subtraction below; it's probably not worth it. */
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
364 r = log(lanczos_sum(x)) - lanczos_g +
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
365 (x-0.5)*(log(x+lanczos_g-0.5)-1);
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
366 }
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
367 else {
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
368 r = log(pi) - log(fabs(sinpi(absx))) - log(absx) -
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
369 (log(lanczos_sum(absx)) - lanczos_g +
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
370 (absx-0.5)*(log(absx+lanczos_g-0.5)-1));
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
371 }
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
372 if (Py_IS_INFINITY(r))
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
373 errno = ERANGE;
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
374 return r;
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
375 }
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
376
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
377
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
378 /*
46507
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
379 wrapper for atan2 that deals directly with special cases before
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
380 delegating to the platform libm for the remaining cases. This
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
381 is necessary to get consistent behaviour across platforms.
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
382 Windows, FreeBSD and alpha Tru64 are amongst platforms that don't
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
383 always follow C99.
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
384 */
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
385
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
386 static double
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
387 m_atan2(double y, double x)
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
388 {
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
389 if (Py_IS_NAN(x) || Py_IS_NAN(y))
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
390 return Py_NAN;
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
391 if (Py_IS_INFINITY(y)) {
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
392 if (Py_IS_INFINITY(x)) {
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
393 if (copysign(1., x) == 1.)
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
394 /* atan2(+-inf, +inf) == +-pi/4 */
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
395 return copysign(0.25*Py_MATH_PI, y);
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
396 else
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
397 /* atan2(+-inf, -inf) == +-pi*3/4 */
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
398 return copysign(0.75*Py_MATH_PI, y);
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
399 }
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
400 /* atan2(+-inf, x) == +-pi/2 for finite x */
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
401 return copysign(0.5*Py_MATH_PI, y);
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
402 }
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
403 if (Py_IS_INFINITY(x) || y == 0.) {
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
404 if (copysign(1., x) == 1.)
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
405 /* atan2(+-y, +inf) = atan2(+-0, +x) = +-0. */
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
406 return copysign(0., y);
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
407 else
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
408 /* atan2(+-y, -inf) = atan2(+-0., -x) = +-pi. */
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
409 return copysign(Py_MATH_PI, y);
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
410 }
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
411 return atan2(y, x);
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
412 }
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
413
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
414 /*
50122
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
415 Various platforms (Solaris, OpenBSD) do nonstandard things for log(0),
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
416 log(-ve), log(NaN). Here are wrappers for log and log10 that deal with
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
417 special values directly, passing positive non-special values through to
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
418 the system log/log10.
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
419 */
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
420
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
421 static double
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
422 m_log(double x)
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
423 {
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
424 if (Py_IS_FINITE(x)) {
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
425 if (x > 0.0)
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
426 return log(x);
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
427 errno = EDOM;
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
428 if (x == 0.0)
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
429 return -Py_HUGE_VAL; /* log(0) = -inf */
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
430 else
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
431 return Py_NAN; /* log(-ve) = nan */
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
432 }
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
433 else if (Py_IS_NAN(x))
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
434 return x; /* log(nan) = nan */
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
435 else if (x > 0.0)
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
436 return x; /* log(inf) = inf */
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
437 else {
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
438 errno = EDOM;
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
439 return Py_NAN; /* log(-inf) = nan */
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
440 }
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
441 }
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
442
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
443 static double
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
444 m_log10(double x)
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
445 {
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
446 if (Py_IS_FINITE(x)) {
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
447 if (x > 0.0)
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
448 return log10(x);
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
449 errno = EDOM;
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
450 if (x == 0.0)
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
451 return -Py_HUGE_VAL; /* log10(0) = -inf */
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
452 else
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
453 return Py_NAN; /* log10(-ve) = nan */
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
454 }
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
455 else if (Py_IS_NAN(x))
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
456 return x; /* log10(nan) = nan */
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
457 else if (x > 0.0)
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
458 return x; /* log10(inf) = inf */
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
459 else {
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
460 errno = EDOM;
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
461 return Py_NAN; /* log10(-inf) = nan */
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
462 }
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
463 }
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
464
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
465
56268
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
466 /* Call is_error when errno != 0, and where x is the result libm
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
467 * returned. is_error will usually set up an exception and return
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
468 * true (1), but may return false (0) without setting up an exception.
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
469 */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
470 static int
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
471 is_error(double x)
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
472 {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
473 int result = 1; /* presumption of guilt */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
474 assert(errno); /* non-zero errno is a precondition for calling */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
475 if (errno == EDOM)
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
476 PyErr_SetString(PyExc_ValueError, "math domain error");
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
477
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
478 else if (errno == ERANGE) {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
479 /* ANSI C generally requires libm functions to set ERANGE
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
480 * on overflow, but also generally *allows* them to set
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
481 * ERANGE on underflow too. There's no consistency about
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
482 * the latter across platforms.
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
483 * Alas, C99 never requires that errno be set.
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
484 * Here we suppress the underflow errors (libm functions
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
485 * should return a zero on underflow, and +- HUGE_VAL on
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
486 * overflow, so testing the result for zero suffices to
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
487 * distinguish the cases).
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
488 *
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
489 * On some platforms (Ubuntu/ia64) it seems that errno can be
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
490 * set to ERANGE for subnormal results that do *not* underflow
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
491 * to zero. So to be safe, we'll ignore ERANGE whenever the
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
492 * function result is less than one in absolute value.
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
493 */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
494 if (fabs(x) < 1.0)
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
495 result = 0;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
496 else
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
497 PyErr_SetString(PyExc_OverflowError,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
498 "math range error");
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
499 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
500 else
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
501 /* Unexpected math error */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
502 PyErr_SetFromErrno(PyExc_ValueError);
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
503 return result;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
504 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
505
50122
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
506 /*
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
507 math_1 is used to wrap a libm function f that takes a double
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
508 arguments and returns a double.
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
509
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
510 The error reporting follows these rules, which are designed to do
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
511 the right thing on C89/C99 platforms and IEEE 754/non IEEE 754
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
512 platforms.
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
513
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
514 - a NaN result from non-NaN inputs causes ValueError to be raised
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
515 - an infinite result from finite inputs causes OverflowError to be
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
516 raised if can_overflow is 1, or raises ValueError if can_overflow
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
517 is 0.
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
518 - if the result is finite and errno == EDOM then ValueError is
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
519 raised
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
520 - if the result is finite and nonzero and errno == ERANGE then
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
521 OverflowError is raised
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
522
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
523 The last rule is used to catch overflow on platforms which follow
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
524 C89 but for which HUGE_VAL is not an infinity.
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
525
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
526 For the majority of one-argument functions these rules are enough
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
527 to ensure that Python's functions behave as specified in 'Annex F'
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
528 of the C99 standard, with the 'invalid' and 'divide-by-zero'
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
529 floating-point exceptions mapping to Python's ValueError and the
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
530 'overflow' floating-point exception mapping to OverflowError.
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
531 math_1 only works for functions that don't have singularities *and*
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
532 the possibility of overflow; fortunately, that covers everything we
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
533 care about right now.
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
534 */
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
535
4635
49745ddb4f69 Renamed
Barry Warsaw <barry@python.org>
parents: 4503
diff changeset
536 static PyObject *
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
537 math_1(PyObject *arg, double (*func) (double), int can_overflow)
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
538 {
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
539 double x, r;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
540 x = PyFloat_AsDouble(arg);
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
541 if (x == -1.0 && PyErr_Occurred())
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
542 return NULL;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
543 errno = 0;
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
544 PyFPE_START_PROTECT("in math_1", return 0);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
545 r = (*func)(x);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
546 PyFPE_END_PROTECT(r);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
547 if (Py_IS_NAN(r)) {
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
548 if (!Py_IS_NAN(x))
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
549 errno = EDOM;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
550 else
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
551 errno = 0;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
552 }
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
553 else if (Py_IS_INFINITY(r)) {
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
554 if (Py_IS_FINITE(x))
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
555 errno = can_overflow ? ERANGE : EDOM;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
556 else
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
557 errno = 0;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
558 }
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
559 if (errno && is_error(r))
15170
09c7ac188ce2 Stop raising OverflowError on underflows reported by libm (errno==ERANGE and
Tim Peters <tim.peters@gmail.com>
parents: 14616
diff changeset
560 return NULL;
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
561 else
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
562 return PyFloat_FromDouble(r);
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
563 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
564
56268
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
565 /* variant of math_1, to be used when the function being wrapped is known to
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
566 set errno properly (that is, errno = EDOM for invalid or divide-by-zero,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
567 errno = ERANGE for overflow). */
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
568
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
569 static PyObject *
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
570 math_1a(PyObject *arg, double (*func) (double))
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
571 {
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
572 double x, r;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
573 x = PyFloat_AsDouble(arg);
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
574 if (x == -1.0 && PyErr_Occurred())
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
575 return NULL;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
576 errno = 0;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
577 PyFPE_START_PROTECT("in math_1a", return 0);
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
578 r = (*func)(x);
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
579 PyFPE_END_PROTECT(r);
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
580 if (errno && is_error(r))
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
581 return NULL;
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
582 return PyFloat_FromDouble(r);
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
583 }
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
584
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
585 /*
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
586 math_2 is used to wrap a libm function f that takes two double
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
587 arguments and returns a double.
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
588
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
589 The error reporting follows these rules, which are designed to do
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
590 the right thing on C89/C99 platforms and IEEE 754/non IEEE 754
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
591 platforms.
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
592
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
593 - a NaN result from non-NaN inputs causes ValueError to be raised
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
594 - an infinite result from finite inputs causes OverflowError to be
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
595 raised.
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
596 - if the result is finite and errno == EDOM then ValueError is
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
597 raised
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
598 - if the result is finite and nonzero and errno == ERANGE then
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
599 OverflowError is raised
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
600
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
601 The last rule is used to catch overflow on platforms which follow
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
602 C89 but for which HUGE_VAL is not an infinity.
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
603
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
604 For most two-argument functions (copysign, fmod, hypot, atan2)
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
605 these rules are enough to ensure that Python's functions behave as
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
606 specified in 'Annex F' of the C99 standard, with the 'invalid' and
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
607 'divide-by-zero' floating-point exceptions mapping to Python's
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
608 ValueError and the 'overflow' floating-point exception mapping to
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
609 OverflowError.
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
610 */
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
611
4635
49745ddb4f69 Renamed
Barry Warsaw <barry@python.org>
parents: 4503
diff changeset
612 static PyObject *
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
613 math_2(PyObject *args, double (*func) (double, double), char *funcname)
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
614 {
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
615 PyObject *ox, *oy;
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
616 double x, y, r;
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
617 if (! PyArg_UnpackTuple(args, funcname, 2, 2, &ox, &oy))
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
618 return NULL;
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
619 x = PyFloat_AsDouble(ox);
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
620 y = PyFloat_AsDouble(oy);
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
621 if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
622 return NULL;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
623 errno = 0;
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
624 PyFPE_START_PROTECT("in math_2", return 0);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
625 r = (*func)(x, y);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
626 PyFPE_END_PROTECT(r);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
627 if (Py_IS_NAN(r)) {
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
628 if (!Py_IS_NAN(x) && !Py_IS_NAN(y))
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
629 errno = EDOM;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
630 else
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
631 errno = 0;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
632 }
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
633 else if (Py_IS_INFINITY(r)) {
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
634 if (Py_IS_FINITE(x) && Py_IS_FINITE(y))
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
635 errno = ERANGE;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
636 else
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
637 errno = 0;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
638 }
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
639 if (errno && is_error(r))
15170
09c7ac188ce2 Stop raising OverflowError on underflows reported by libm (errno==ERANGE and
Tim Peters <tim.peters@gmail.com>
parents: 14616
diff changeset
640 return NULL;
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
641 else
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
642 return PyFloat_FromDouble(r);
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
643 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
644
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
645 #define FUNC1(funcname, func, can_overflow, docstring) \
13326
24717405dd89 ANSI-fication, remove Py_PROTO, etc.
Fred Drake <fdrake@acm.org>
parents: 13309
diff changeset
646 static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
647 return math_1(args, func, can_overflow); \
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
648 }\
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
649 PyDoc_STRVAR(math_##funcname##_doc, docstring);
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
650
56268
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
651 #define FUNC1A(funcname, func, docstring) \
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
652 static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
653 return math_1a(args, func); \
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
654 }\
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
655 PyDoc_STRVAR(math_##funcname##_doc, docstring);
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
656
13326
24717405dd89 ANSI-fication, remove Py_PROTO, etc.
Fred Drake <fdrake@acm.org>
parents: 13309
diff changeset
657 #define FUNC2(funcname, func, docstring) \
24717405dd89 ANSI-fication, remove Py_PROTO, etc.
Fred Drake <fdrake@acm.org>
parents: 13309
diff changeset
658 static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
659 return math_2(args, func, #funcname); \
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
660 }\
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
661 PyDoc_STRVAR(math_##funcname##_doc, docstring);
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
662
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
663 FUNC1(acos, acos, 0,
19048
e282d6b2b758 Part of SF patch [#431848] mathmodule.c: doc strings & conversion, from
Tim Peters <tim.peters@gmail.com>
parents: 18066
diff changeset
664 "acos(x)\n\nReturn the arc cosine (measured in radians) of x.")
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
665 FUNC1(acosh, acosh, 0,
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
666 "acosh(x)\n\nReturn the hyperbolic arc cosine (measured in radians) of x.")
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
667 FUNC1(asin, asin, 0,
19048
e282d6b2b758 Part of SF patch [#431848] mathmodule.c: doc strings & conversion, from
Tim Peters <tim.peters@gmail.com>
parents: 18066
diff changeset
668 "asin(x)\n\nReturn the arc sine (measured in radians) of x.")
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
669 FUNC1(asinh, asinh, 0,
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
670 "asinh(x)\n\nReturn the hyperbolic arc sine (measured in radians) of x.")
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
671 FUNC1(atan, atan, 0,
19048
e282d6b2b758 Part of SF patch [#431848] mathmodule.c: doc strings & conversion, from
Tim Peters <tim.peters@gmail.com>
parents: 18066
diff changeset
672 "atan(x)\n\nReturn the arc tangent (measured in radians) of x.")
46507
022296032d8f math.atan2 is misbehaving on Windows; this patch
Mark Dickinson <dickinsm@gmail.com>
parents: 46500
diff changeset
673 FUNC2(atan2, m_atan2,
19048
e282d6b2b758 Part of SF patch [#431848] mathmodule.c: doc strings & conversion, from
Tim Peters <tim.peters@gmail.com>
parents: 18066
diff changeset
674 "atan2(y, x)\n\nReturn the arc tangent (measured in radians) of y/x.\n"
e282d6b2b758 Part of SF patch [#431848] mathmodule.c: doc strings & conversion, from
Tim Peters <tim.peters@gmail.com>
parents: 18066
diff changeset
675 "Unlike atan(y/x), the signs of both x and y are considered.")
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
676 FUNC1(atanh, atanh, 0,
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
677 "atanh(x)\n\nReturn the hyperbolic arc tangent (measured in radians) of x.")
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
678 FUNC1(ceil, ceil, 0,
44488
94eeaeeb3ce9 Continue rolling back pep-3141 changes that changed behavior from 2.5. This
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44453
diff changeset
679 "ceil(x)\n\nReturn the ceiling of x as a float.\n"
94eeaeeb3ce9 Continue rolling back pep-3141 changes that changed behavior from 2.5. This
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44453
diff changeset
680 "This is the smallest integral value >= x.")
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
681 FUNC2(copysign, copysign,
56977
7e02371aa506 Use a single style for all the docstrings in the math module.
Georg Brandl <georg@python.org>
parents: 56974
diff changeset
682 "copysign(x, y)\n\nReturn x with the sign of y.")
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
683 FUNC1(cos, cos, 0,
19048
e282d6b2b758 Part of SF patch [#431848] mathmodule.c: doc strings & conversion, from
Tim Peters <tim.peters@gmail.com>
parents: 18066
diff changeset
684 "cos(x)\n\nReturn the cosine of x (measured in radians).")
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
685 FUNC1(cosh, cosh, 1,
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
686 "cosh(x)\n\nReturn the hyperbolic cosine of x.")
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
687 FUNC1(exp, exp, 1,
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
688 "exp(x)\n\nReturn e raised to the power of x.")
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
689 FUNC1(fabs, fabs, 0,
19048
e282d6b2b758 Part of SF patch [#431848] mathmodule.c: doc strings & conversion, from
Tim Peters <tim.peters@gmail.com>
parents: 18066
diff changeset
690 "fabs(x)\n\nReturn the absolute value of the float x.")
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
691 FUNC1(floor, floor, 0,
44488
94eeaeeb3ce9 Continue rolling back pep-3141 changes that changed behavior from 2.5. This
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44453
diff changeset
692 "floor(x)\n\nReturn the floor of x as a float.\n"
94eeaeeb3ce9 Continue rolling back pep-3141 changes that changed behavior from 2.5. This
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44453
diff changeset
693 "This is the largest integral value <= x.")
56268
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
694 FUNC1A(gamma, m_tgamma,
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
695 "gamma(x)\n\nGamma function at x.")
57655
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
696 FUNC1A(lgamma, m_lgamma,
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
697 "lgamma(x)\n\nNatural logarithm of absolute value of Gamma function at x.")
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
698 FUNC1(log1p, log1p, 1,
56977
7e02371aa506 Use a single style for all the docstrings in the math module.
Georg Brandl <georg@python.org>
parents: 56974
diff changeset
699 "log1p(x)\n\nReturn the natural logarithm of 1+x (base e).\n"
7e02371aa506 Use a single style for all the docstrings in the math module.
Georg Brandl <georg@python.org>
parents: 56974
diff changeset
700 "The result is computed in a way which is accurate for x near zero.")
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
701 FUNC1(sin, sin, 0,
19048
e282d6b2b758 Part of SF patch [#431848] mathmodule.c: doc strings & conversion, from
Tim Peters <tim.peters@gmail.com>
parents: 18066
diff changeset
702 "sin(x)\n\nReturn the sine of x (measured in radians).")
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
703 FUNC1(sinh, sinh, 1,
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
704 "sinh(x)\n\nReturn the hyperbolic sine of x.")
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
705 FUNC1(sqrt, sqrt, 0,
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
706 "sqrt(x)\n\nReturn the square root of x.")
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
707 FUNC1(tan, tan, 0,
19048
e282d6b2b758 Part of SF patch [#431848] mathmodule.c: doc strings & conversion, from
Tim Peters <tim.peters@gmail.com>
parents: 18066
diff changeset
708 "tan(x)\n\nReturn the tangent of x (measured in radians).")
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
709 FUNC1(tanh, tanh, 0,
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
710 "tanh(x)\n\nReturn the hyperbolic tangent of x.")
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
711
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
712 /* Precision summation function as msum() by Raymond Hettinger in
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
713 <http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/393090>,
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
714 enhanced with the exact partials sum and roundoff from Mark
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
715 Dickinson's post at <http://bugs.python.org/file10357/msum4.py>.
47220
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
716 See those links for more details, proofs and other references.
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
717
47220
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
718 Note 1: IEEE 754R floating point semantics are assumed,
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
719 but the current implementation does not re-establish special
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
720 value semantics across iterations (i.e. handling -Inf + Inf).
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
721
47220
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
722 Note 2: No provision is made for intermediate overflow handling;
47370
9e6e6b817f32 Fix two typos.
Raymond Hettinger <python@rcn.com>
parents: 47220
diff changeset
723 therefore, sum([1e+308, 1e-308, 1e+308]) returns 1e+308 while
47220
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
724 sum([1e+308, 1e+308, 1e-308]) raises an OverflowError due to the
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
725 overflow of the first partial sum.
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
726
47777
c39263e94c33 Fix comment typos
Andrew M. Kuchling <amk@amk.ca>
parents: 47757
diff changeset
727 Note 3: The intermediate values lo, yr, and hi are declared volatile so
47783
a7186fee7596 Fix another typo in math_sum comment
Mark Dickinson <dickinsm@gmail.com>
parents: 47777
diff changeset
728 aggressive compilers won't algebraically reduce lo to always be exactly 0.0.
47532
6cfa297c6555 Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
Raymond Hettinger <python@rcn.com>
parents: 47531
diff changeset
729 Also, the volatile declaration forces the values to be stored in memory as
6cfa297c6555 Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
Raymond Hettinger <python@rcn.com>
parents: 47531
diff changeset
730 regular doubles instead of extended long precision (80-bit) values. This
47777
c39263e94c33 Fix comment typos
Andrew M. Kuchling <amk@amk.ca>
parents: 47757
diff changeset
731 prevents double rounding because any addition or subtraction of two doubles
47532
6cfa297c6555 Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
Raymond Hettinger <python@rcn.com>
parents: 47531
diff changeset
732 can be resolved exactly into double-sized hi and lo values. As long as the
6cfa297c6555 Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
Raymond Hettinger <python@rcn.com>
parents: 47531
diff changeset
733 hi value gets forced into a double before yr and lo are computed, the extra
6cfa297c6555 Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
Raymond Hettinger <python@rcn.com>
parents: 47531
diff changeset
734 bits in downstream extended precision operations (x87 for example) will be
6cfa297c6555 Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
Raymond Hettinger <python@rcn.com>
parents: 47531
diff changeset
735 exactly zero and therefore can be losslessly stored back into a double,
6cfa297c6555 Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
Raymond Hettinger <python@rcn.com>
parents: 47531
diff changeset
736 thereby preventing double rounding.
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
737
47532
6cfa297c6555 Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
Raymond Hettinger <python@rcn.com>
parents: 47531
diff changeset
738 Note 4: A similar implementation is in Modules/cmathmodule.c.
6cfa297c6555 Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
Raymond Hettinger <python@rcn.com>
parents: 47531
diff changeset
739 Be sure to update both when making changes.
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
740
48102
b35ce954a392 Replace math.sum with math.fsum in a couple of comments
Mark Dickinson <dickinsm@gmail.com>
parents: 48101
diff changeset
741 Note 5: The signature of math.fsum() differs from __builtin__.sum()
47220
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
742 because the start argument doesn't make sense in the context of
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
743 accurate summation. Since the partials table is collapsed before
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
744 returning a result, sum(seq2, start=sum(seq1)) may not equal the
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
745 accurate result returned by sum(itertools.chain(seq1, seq2)).
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
746 */
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
747
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
748 #define NUM_PARTIALS 32 /* initial partials array size, on stack */
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
749
47220
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
750 /* Extend the partials array p[] by doubling its size. */
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
751 static int /* non-zero on error */
48101
8d05dda735f8 Rename math.sum to math.fsum
Mark Dickinson <dickinsm@gmail.com>
parents: 48099
diff changeset
752 _fsum_realloc(double **p_ptr, Py_ssize_t n,
47532
6cfa297c6555 Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
Raymond Hettinger <python@rcn.com>
parents: 47531
diff changeset
753 double *ps, Py_ssize_t *m_ptr)
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
754 {
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
755 void *v = NULL;
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
756 Py_ssize_t m = *m_ptr;
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
757
47532
6cfa297c6555 Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
Raymond Hettinger <python@rcn.com>
parents: 47531
diff changeset
758 m += m; /* double */
6cfa297c6555 Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
Raymond Hettinger <python@rcn.com>
parents: 47531
diff changeset
759 if (n < m && m < (PY_SSIZE_T_MAX / sizeof(double))) {
6cfa297c6555 Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
Raymond Hettinger <python@rcn.com>
parents: 47531
diff changeset
760 double *p = *p_ptr;
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
761 if (p == ps) {
47532
6cfa297c6555 Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
Raymond Hettinger <python@rcn.com>
parents: 47531
diff changeset
762 v = PyMem_Malloc(sizeof(double) * m);
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
763 if (v != NULL)
47532
6cfa297c6555 Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
Raymond Hettinger <python@rcn.com>
parents: 47531
diff changeset
764 memcpy(v, ps, sizeof(double) * n);
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
765 }
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
766 else
47532
6cfa297c6555 Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
Raymond Hettinger <python@rcn.com>
parents: 47531
diff changeset
767 v = PyMem_Realloc(p, sizeof(double) * m);
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
768 }
47220
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
769 if (v == NULL) { /* size overflow or no memory */
48101
8d05dda735f8 Rename math.sum to math.fsum
Mark Dickinson <dickinsm@gmail.com>
parents: 48099
diff changeset
770 PyErr_SetString(PyExc_MemoryError, "math.fsum partials");
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
771 return 1;
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
772 }
47532
6cfa297c6555 Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
Raymond Hettinger <python@rcn.com>
parents: 47531
diff changeset
773 *p_ptr = (double*) v;
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
774 *m_ptr = m;
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
775 return 0;
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
776 }
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
777
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
778 /* Full precision summation of a sequence of floats.
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
779
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
780 def msum(iterable):
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
781 partials = [] # sorted, non-overlapping partial sums
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
782 for x in iterable:
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
783 i = 0
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
784 for y in partials:
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
785 if abs(x) < abs(y):
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
786 x, y = y, x
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
787 hi = x + y
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
788 lo = y - (hi - x)
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
789 if lo:
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
790 partials[i] = lo
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
791 i += 1
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
792 x = hi
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
793 partials[i:] = [x]
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
794 return sum_exact(partials)
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
795
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
796 Rounded x+y stored in hi with the roundoff stored in lo. Together hi+lo
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
797 are exactly equal to x+y. The inner loop applies hi/lo summation to each
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
798 partial so that the list of partial sums remains exact.
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
799
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
800 Sum_exact() adds the partial sums exactly and correctly rounds the final
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
801 result (using the round-half-to-even rule). The items in partials remain
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
802 non-zero, non-special, non-overlapping and strictly increasing in
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
803 magnitude, but possibly not all having the same sign.
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
804
47220
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
805 Depends on IEEE 754 arithmetic guarantees and half-even rounding.
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
806 */
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
807
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
808 static PyObject*
48101
8d05dda735f8 Rename math.sum to math.fsum
Mark Dickinson <dickinsm@gmail.com>
parents: 48099
diff changeset
809 math_fsum(PyObject *self, PyObject *seq)
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
810 {
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
811 PyObject *item, *iter, *sum = NULL;
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
812 Py_ssize_t i, j, n = 0, m = NUM_PARTIALS;
47532
6cfa297c6555 Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
Raymond Hettinger <python@rcn.com>
parents: 47531
diff changeset
813 double x, y, t, ps[NUM_PARTIALS], *p = ps;
48099
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
814 double xsave, special_sum = 0.0, inf_sum = 0.0;
47532
6cfa297c6555 Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
Raymond Hettinger <python@rcn.com>
parents: 47531
diff changeset
815 volatile double hi, yr, lo;
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
816
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
817 iter = PyObject_GetIter(seq);
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
818 if (iter == NULL)
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
819 return NULL;
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
820
48101
8d05dda735f8 Rename math.sum to math.fsum
Mark Dickinson <dickinsm@gmail.com>
parents: 48099
diff changeset
821 PyFPE_START_PROTECT("fsum", Py_DECREF(iter); return NULL)
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
822
47220
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
823 for(;;) { /* for x in iterable */
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
824 assert(0 <= n && n <= m);
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
825 assert((m == NUM_PARTIALS && p == ps) ||
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
826 (m > NUM_PARTIALS && p != NULL));
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
827
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
828 item = PyIter_Next(iter);
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
829 if (item == NULL) {
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
830 if (PyErr_Occurred())
48101
8d05dda735f8 Rename math.sum to math.fsum
Mark Dickinson <dickinsm@gmail.com>
parents: 48099
diff changeset
831 goto _fsum_error;
47220
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
832 break;
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
833 }
47532
6cfa297c6555 Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
Raymond Hettinger <python@rcn.com>
parents: 47531
diff changeset
834 x = PyFloat_AsDouble(item);
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
835 Py_DECREF(item);
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
836 if (PyErr_Occurred())
48101
8d05dda735f8 Rename math.sum to math.fsum
Mark Dickinson <dickinsm@gmail.com>
parents: 48099
diff changeset
837 goto _fsum_error;
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
838
48099
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
839 xsave = x;
47220
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
840 for (i = j = 0; j < n; j++) { /* for y in partials */
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
841 y = p[j];
47395
bba29f462bcc * Mark intermedidate computes values (hi, lo, yr) as volatile.
Raymond Hettinger <python@rcn.com>
parents: 47370
diff changeset
842 if (fabs(x) < fabs(y)) {
48099
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
843 t = x; x = y; y = t;
47395
bba29f462bcc * Mark intermedidate computes values (hi, lo, yr) as volatile.
Raymond Hettinger <python@rcn.com>
parents: 47370
diff changeset
844 }
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
845 hi = x + y;
47395
bba29f462bcc * Mark intermedidate computes values (hi, lo, yr) as volatile.
Raymond Hettinger <python@rcn.com>
parents: 47370
diff changeset
846 yr = hi - x;
bba29f462bcc * Mark intermedidate computes values (hi, lo, yr) as volatile.
Raymond Hettinger <python@rcn.com>
parents: 47370
diff changeset
847 lo = y - yr;
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
848 if (lo != 0.0)
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
849 p[i++] = lo;
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
850 x = hi;
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
851 }
48099
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
852
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
853 n = i; /* ps[i:] = [x] */
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
854 if (x != 0.0) {
48099
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
855 if (! Py_IS_FINITE(x)) {
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
856 /* a nonfinite x could arise either as
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
857 a result of intermediate overflow, or
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
858 as a result of a nan or inf in the
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
859 summands */
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
860 if (Py_IS_FINITE(xsave)) {
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
861 PyErr_SetString(PyExc_OverflowError,
48101
8d05dda735f8 Rename math.sum to math.fsum
Mark Dickinson <dickinsm@gmail.com>
parents: 48099
diff changeset
862 "intermediate overflow in fsum");
8d05dda735f8 Rename math.sum to math.fsum
Mark Dickinson <dickinsm@gmail.com>
parents: 48099
diff changeset
863 goto _fsum_error;
48099
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
864 }
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
865 if (Py_IS_INFINITY(xsave))
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
866 inf_sum += xsave;
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
867 special_sum += xsave;
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
868 /* reset partials */
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
869 n = 0;
48099
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
870 }
48101
8d05dda735f8 Rename math.sum to math.fsum
Mark Dickinson <dickinsm@gmail.com>
parents: 48099
diff changeset
871 else if (n >= m && _fsum_realloc(&p, n, ps, &m))
8d05dda735f8 Rename math.sum to math.fsum
Mark Dickinson <dickinsm@gmail.com>
parents: 48099
diff changeset
872 goto _fsum_error;
48099
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
873 else
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
874 p[n++] = x;
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
875 }
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
876 }
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
877
48099
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
878 if (special_sum != 0.0) {
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
879 if (Py_IS_NAN(inf_sum))
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
880 PyErr_SetString(PyExc_ValueError,
48101
8d05dda735f8 Rename math.sum to math.fsum
Mark Dickinson <dickinsm@gmail.com>
parents: 48099
diff changeset
881 "-inf + inf in fsum");
48099
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
882 else
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
883 sum = PyFloat_FromDouble(special_sum);
48101
8d05dda735f8 Rename math.sum to math.fsum
Mark Dickinson <dickinsm@gmail.com>
parents: 48099
diff changeset
884 goto _fsum_error;
48099
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
885 }
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
886
47395
bba29f462bcc * Mark intermedidate computes values (hi, lo, yr) as volatile.
Raymond Hettinger <python@rcn.com>
parents: 47370
diff changeset
887 hi = 0.0;
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
888 if (n > 0) {
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
889 hi = p[--n];
48099
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
890 /* sum_exact(ps, hi) from the top, stop when the sum becomes
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
891 inexact. */
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
892 while (n > 0) {
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
893 x = hi;
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
894 y = p[--n];
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
895 assert(fabs(y) < fabs(x));
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
896 hi = x + y;
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
897 yr = hi - x;
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
898 lo = y - yr;
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
899 if (lo != 0.0)
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
900 break;
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
901 }
48099
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
902 /* Make half-even rounding work across multiple partials.
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
903 Needed so that sum([1e-16, 1, 1e16]) will round-up the last
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
904 digit to two instead of down to zero (the 1e-16 makes the 1
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
905 slightly closer to two). With a potential 1 ULP rounding
48102
b35ce954a392 Replace math.sum with math.fsum in a couple of comments
Mark Dickinson <dickinsm@gmail.com>
parents: 48101
diff changeset
906 error fixed-up, math.fsum() can guarantee commutativity. */
48099
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
907 if (n > 0 && ((lo < 0.0 && p[n-1] < 0.0) ||
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
908 (lo > 0.0 && p[n-1] > 0.0))) {
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
909 y = lo * 2.0;
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
910 x = hi + y;
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
911 yr = x - hi;
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
912 if (y == yr)
b40e13bcb9ea Fix special-value handling for math.sum.
Mark Dickinson <dickinsm@gmail.com>
parents: 47783
diff changeset
913 hi = x;
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
914 }
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
915 }
47532
6cfa297c6555 Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
Raymond Hettinger <python@rcn.com>
parents: 47531
diff changeset
916 sum = PyFloat_FromDouble(hi);
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
917
48101
8d05dda735f8 Rename math.sum to math.fsum
Mark Dickinson <dickinsm@gmail.com>
parents: 48099
diff changeset
918 _fsum_error:
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
919 PyFPE_END_PROTECT(hi)
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
920 Py_DECREF(iter);
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
921 if (p != ps)
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
922 PyMem_Free(p);
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
923 return sum;
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
924 }
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
925
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
926 #undef NUM_PARTIALS
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
927
48101
8d05dda735f8 Rename math.sum to math.fsum
Mark Dickinson <dickinsm@gmail.com>
parents: 48099
diff changeset
928 PyDoc_STRVAR(math_fsum_doc,
56974
c6d62340aebf Use the correct function name in docstring.
Georg Brandl <georg@python.org>
parents: 56268
diff changeset
929 "fsum(iterable)\n\n\
47220
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
930 Return an accurate floating point sum of values in the iterable.\n\
71deee6b941e Tweak the comments and formatting.
Raymond Hettinger <python@rcn.com>
parents: 47216
diff changeset
931 Assumes IEEE-754 floating point arithmetic.");
47216
2fffdedb10f8 Issue #2819: Add math.sum, a function that sums a sequence of floats
Mark Dickinson <dickinsm@gmail.com>
parents: 46797
diff changeset
932
47529
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
933 static PyObject *
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
934 math_factorial(PyObject *self, PyObject *arg)
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
935 {
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
936 long i, x;
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
937 PyObject *result, *iobj, *newresult;
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
938
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
939 if (PyFloat_Check(arg)) {
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
940 double dx = PyFloat_AS_DOUBLE((PyFloatObject *)arg);
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
941 if (dx != floor(dx)) {
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
942 PyErr_SetString(PyExc_ValueError,
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
943 "factorial() only accepts integral values");
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
944 return NULL;
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
945 }
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
946 }
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
947
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
948 x = PyInt_AsLong(arg);
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
949 if (x == -1 && PyErr_Occurred())
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
950 return NULL;
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
951 if (x < 0) {
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
952 PyErr_SetString(PyExc_ValueError,
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
953 "factorial() not defined for negative values");
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
954 return NULL;
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
955 }
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
956
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
957 result = (PyObject *)PyInt_FromLong(1);
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
958 if (result == NULL)
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
959 return NULL;
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
960 for (i=1 ; i<=x ; i++) {
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
961 iobj = (PyObject *)PyInt_FromLong(i);
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
962 if (iobj == NULL)
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
963 goto error;
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
964 newresult = PyNumber_Multiply(result, iobj);
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
965 Py_DECREF(iobj);
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
966 if (newresult == NULL)
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
967 goto error;
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
968 Py_DECREF(result);
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
969 result = newresult;
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
970 }
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
971 return result;
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
972
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
973 error:
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
974 Py_DECREF(result);
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
975 return NULL;
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
976 }
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
977
50236
670204cf23e2 beef up docstring
Benjamin Peterson <benjamin@python.org>
parents: 50122
diff changeset
978 PyDoc_STRVAR(math_factorial_doc,
670204cf23e2 beef up docstring
Benjamin Peterson <benjamin@python.org>
parents: 50122
diff changeset
979 "factorial(x) -> Integral\n"
670204cf23e2 beef up docstring
Benjamin Peterson <benjamin@python.org>
parents: 50122
diff changeset
980 "\n"
670204cf23e2 beef up docstring
Benjamin Peterson <benjamin@python.org>
parents: 50122
diff changeset
981 "Find x!. Raise a ValueError if x is negative or non-integral.");
47529
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
982
4635
49745ddb4f69 Renamed
Barry Warsaw <barry@python.org>
parents: 4503
diff changeset
983 static PyObject *
45079
492b302aded6 Move __builtins__.trunc() to math.trunc() per
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44947
diff changeset
984 math_trunc(PyObject *self, PyObject *number)
492b302aded6 Move __builtins__.trunc() to math.trunc() per
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44947
diff changeset
985 {
492b302aded6 Move __builtins__.trunc() to math.trunc() per
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44947
diff changeset
986 return PyObject_CallMethod(number, "__trunc__", NULL);
492b302aded6 Move __builtins__.trunc() to math.trunc() per
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44947
diff changeset
987 }
492b302aded6 Move __builtins__.trunc() to math.trunc() per
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44947
diff changeset
988
492b302aded6 Move __builtins__.trunc() to math.trunc() per
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44947
diff changeset
989 PyDoc_STRVAR(math_trunc_doc,
492b302aded6 Move __builtins__.trunc() to math.trunc() per
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44947
diff changeset
990 "trunc(x:Real) -> Integral\n"
492b302aded6 Move __builtins__.trunc() to math.trunc() per
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44947
diff changeset
991 "\n"
45102
ce9816f53690 Neaten-up a bit.
Raymond Hettinger <python@rcn.com>
parents: 45079
diff changeset
992 "Truncates x to the nearest Integral toward 0. Uses the __trunc__ magic method.");
45079
492b302aded6 Move __builtins__.trunc() to math.trunc() per
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44947
diff changeset
993
492b302aded6 Move __builtins__.trunc() to math.trunc() per
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44947
diff changeset
994 static PyObject *
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
995 math_frexp(PyObject *self, PyObject *arg)
407
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
996 {
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
997 int i;
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
998 double x = PyFloat_AsDouble(arg);
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
999 if (x == -1.0 && PyErr_Occurred())
407
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1000 return NULL;
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1001 /* deal with special cases directly, to sidestep platform
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1002 differences */
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1003 if (Py_IS_NAN(x) || Py_IS_INFINITY(x) || !x) {
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1004 i = 0;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1005 }
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1006 else {
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1007 PyFPE_START_PROTECT("in math_frexp", return 0);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1008 x = frexp(x, &i);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1009 PyFPE_END_PROTECT(x);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1010 }
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1011 return Py_BuildValue("(di)", x, i);
407
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1012 }
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1013
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
1014 PyDoc_STRVAR(math_frexp_doc,
19712
b4521436e8f8 Mechanical fiddling to make this easier to work with in my editor.
Tim Peters <tim.peters@gmail.com>
parents: 19048
diff changeset
1015 "frexp(x)\n"
b4521436e8f8 Mechanical fiddling to make this easier to work with in my editor.
Tim Peters <tim.peters@gmail.com>
parents: 19048
diff changeset
1016 "\n"
b4521436e8f8 Mechanical fiddling to make this easier to work with in my editor.
Tim Peters <tim.peters@gmail.com>
parents: 19048
diff changeset
1017 "Return the mantissa and exponent of x, as pair (m, e).\n"
b4521436e8f8 Mechanical fiddling to make this easier to work with in my editor.
Tim Peters <tim.peters@gmail.com>
parents: 19048
diff changeset
1018 "m is a float and e is an int, such that x = m * 2.**e.\n"
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
1019 "If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0.");
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
1020
4635
49745ddb4f69 Renamed
Barry Warsaw <barry@python.org>
parents: 4503
diff changeset
1021 static PyObject *
13326
24717405dd89 ANSI-fication, remove Py_PROTO, etc.
Fred Drake <fdrake@acm.org>
parents: 13309
diff changeset
1022 math_ldexp(PyObject *self, PyObject *args)
407
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1023 {
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1024 double x, r;
46797
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1025 PyObject *oexp;
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1026 long exp;
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1027 if (! PyArg_ParseTuple(args, "dO:ldexp", &x, &oexp))
407
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1028 return NULL;
46797
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1029
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1030 if (PyLong_Check(oexp)) {
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1031 /* on overflow, replace exponent with either LONG_MAX
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1032 or LONG_MIN, depending on the sign. */
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1033 exp = PyLong_AsLong(oexp);
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1034 if (exp == -1 && PyErr_Occurred()) {
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1035 if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1036 if (Py_SIZE(oexp) < 0) {
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1037 exp = LONG_MIN;
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1038 }
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1039 else {
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1040 exp = LONG_MAX;
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1041 }
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1042 PyErr_Clear();
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1043 }
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1044 else {
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1045 /* propagate any unexpected exception */
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1046 return NULL;
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1047 }
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1048 }
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1049 }
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1050 else if (PyInt_Check(oexp)) {
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1051 exp = PyInt_AS_LONG(oexp);
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1052 }
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1053 else {
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1054 PyErr_SetString(PyExc_TypeError,
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1055 "Expected an int or long as second argument "
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1056 "to ldexp.");
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1057 return NULL;
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1058 }
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1059
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1060 if (x == 0. || !Py_IS_FINITE(x)) {
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1061 /* NaNs, zeros and infinities are returned unchanged */
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1062 r = x;
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1063 errno = 0;
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1064 } else if (exp > INT_MAX) {
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1065 /* overflow */
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1066 r = copysign(Py_HUGE_VAL, x);
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1067 errno = ERANGE;
46797
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1068 } else if (exp < INT_MIN) {
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1069 /* underflow to +-0 */
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1070 r = copysign(0., x);
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1071 errno = 0;
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1072 } else {
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1073 errno = 0;
46797
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1074 PyFPE_START_PROTECT("in math_ldexp", return 0);
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1075 r = ldexp(x, (int)exp);
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1076 PyFPE_END_PROTECT(r);
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1077 if (Py_IS_INFINITY(r))
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1078 errno = ERANGE;
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1079 }
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1080
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1081 if (errno && is_error(r))
15170
09c7ac188ce2 Stop raising OverflowError on underflows reported by libm (errno==ERANGE and
Tim Peters <tim.peters@gmail.com>
parents: 14616
diff changeset
1082 return NULL;
46797
fd0b894bc90c Issue #2487. math.ldexp(x, n) raised OverflowError when n was large and
Mark Dickinson <dickinsm@gmail.com>
parents: 46509
diff changeset
1083 return PyFloat_FromDouble(r);
407
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1084 }
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1085
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
1086 PyDoc_STRVAR(math_ldexp_doc,
56977
7e02371aa506 Use a single style for all the docstrings in the math module.
Georg Brandl <georg@python.org>
parents: 56974
diff changeset
1087 "ldexp(x, i)\n\n\
7e02371aa506 Use a single style for all the docstrings in the math module.
Georg Brandl <georg@python.org>
parents: 56974
diff changeset
1088 Return x * (2**i).");
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
1089
4635
49745ddb4f69 Renamed
Barry Warsaw <barry@python.org>
parents: 4503
diff changeset
1090 static PyObject *
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1091 math_modf(PyObject *self, PyObject *arg)
407
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1092 {
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1093 double y, x = PyFloat_AsDouble(arg);
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1094 if (x == -1.0 && PyErr_Occurred())
407
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1095 return NULL;
46499
80b16595e462 FreeBSD doesn't follow C99 for modf(inf); so add explicit
Mark Dickinson <dickinsm@gmail.com>
parents: 46490
diff changeset
1096 /* some platforms don't do the right thing for NaNs and
80b16595e462 FreeBSD doesn't follow C99 for modf(inf); so add explicit
Mark Dickinson <dickinsm@gmail.com>
parents: 46490
diff changeset
1097 infinities, so we take care of special cases directly. */
80b16595e462 FreeBSD doesn't follow C99 for modf(inf); so add explicit
Mark Dickinson <dickinsm@gmail.com>
parents: 46490
diff changeset
1098 if (!Py_IS_FINITE(x)) {
80b16595e462 FreeBSD doesn't follow C99 for modf(inf); so add explicit
Mark Dickinson <dickinsm@gmail.com>
parents: 46490
diff changeset
1099 if (Py_IS_INFINITY(x))
80b16595e462 FreeBSD doesn't follow C99 for modf(inf); so add explicit
Mark Dickinson <dickinsm@gmail.com>
parents: 46490
diff changeset
1100 return Py_BuildValue("(dd)", copysign(0., x), x);
80b16595e462 FreeBSD doesn't follow C99 for modf(inf); so add explicit
Mark Dickinson <dickinsm@gmail.com>
parents: 46490
diff changeset
1101 else if (Py_IS_NAN(x))
80b16595e462 FreeBSD doesn't follow C99 for modf(inf); so add explicit
Mark Dickinson <dickinsm@gmail.com>
parents: 46490
diff changeset
1102 return Py_BuildValue("(dd)", x, x);
80b16595e462 FreeBSD doesn't follow C99 for modf(inf); so add explicit
Mark Dickinson <dickinsm@gmail.com>
parents: 46490
diff changeset
1103 }
80b16595e462 FreeBSD doesn't follow C99 for modf(inf); so add explicit
Mark Dickinson <dickinsm@gmail.com>
parents: 46490
diff changeset
1104
407
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1105 errno = 0;
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1106 PyFPE_START_PROTECT("in math_modf", return 0);
407
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1107 x = modf(x, &y);
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1108 PyFPE_END_PROTECT(x);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1109 return Py_BuildValue("(dd)", x, y);
407
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1110 }
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1111
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
1112 PyDoc_STRVAR(math_modf_doc,
19712
b4521436e8f8 Mechanical fiddling to make this easier to work with in my editor.
Tim Peters <tim.peters@gmail.com>
parents: 19048
diff changeset
1113 "modf(x)\n"
b4521436e8f8 Mechanical fiddling to make this easier to work with in my editor.
Tim Peters <tim.peters@gmail.com>
parents: 19048
diff changeset
1114 "\n"
b4521436e8f8 Mechanical fiddling to make this easier to work with in my editor.
Tim Peters <tim.peters@gmail.com>
parents: 19048
diff changeset
1115 "Return the fractional and integer parts of x. Both results carry the sign\n"
50243
589edf615adb remove redundant sentence
Benjamin Peterson <benjamin@python.org>
parents: 50236
diff changeset
1116 "of x and are floats.");
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
1117
19713
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1118 /* A decent logarithm is easy to compute even for huge longs, but libm can't
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1119 do that by itself -- loghelper can. func is log or log10, and name is
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1120 "log" or "log10". Note that overflow isn't possible: a long can contain
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1121 no more than INT_MAX * SHIFT bits, so has value certainly less than
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1122 2**(2**64 * 2**16) == 2**2**80, and log2 of that is 2**80, which is
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1123 small enough to fit in an IEEE single. log and log10 are even smaller.
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1124 */
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1125
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1126 static PyObject*
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1127 loghelper(PyObject* arg, double (*func)(double), char *funcname)
19713
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1128 {
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1129 /* If it is long, do it ourselves. */
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1130 if (PyLong_Check(arg)) {
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1131 double x;
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1132 int e;
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1133 x = _PyLong_AsScaledDouble(arg, &e);
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1134 if (x <= 0.0) {
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1135 PyErr_SetString(PyExc_ValueError,
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1136 "math domain error");
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1137 return NULL;
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1138 }
44947
8e435bdd4bc8 setup.py doesn't pick up changes to a header file
Christian Heimes <christian@cheimes.de>
parents: 44940
diff changeset
1139 /* Value is ~= x * 2**(e*PyLong_SHIFT), so the log ~=
8e435bdd4bc8 setup.py doesn't pick up changes to a header file
Christian Heimes <christian@cheimes.de>
parents: 44940
diff changeset
1140 log(x) + log(2) * e * PyLong_SHIFT.
8e435bdd4bc8 setup.py doesn't pick up changes to a header file
Christian Heimes <christian@cheimes.de>
parents: 44940
diff changeset
1141 CAUTION: e*PyLong_SHIFT may overflow using int arithmetic,
19713
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1142 so force use of double. */
44947
8e435bdd4bc8 setup.py doesn't pick up changes to a header file
Christian Heimes <christian@cheimes.de>
parents: 44940
diff changeset
1143 x = func(x) + (e * (double)PyLong_SHIFT) * func(2.0);
19713
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1144 return PyFloat_FromDouble(x);
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1145 }
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1146
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1147 /* Else let libm handle it by itself. */
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1148 return math_1(arg, func, 0);
19713
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1149 }
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1150
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1151 static PyObject *
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1152 math_log(PyObject *self, PyObject *args)
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1153 {
26661
b12e326b4ea2 Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
Raymond Hettinger <python@rcn.com>
parents: 24471
diff changeset
1154 PyObject *arg;
b12e326b4ea2 Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
Raymond Hettinger <python@rcn.com>
parents: 24471
diff changeset
1155 PyObject *base = NULL;
b12e326b4ea2 Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
Raymond Hettinger <python@rcn.com>
parents: 24471
diff changeset
1156 PyObject *num, *den;
b12e326b4ea2 Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
Raymond Hettinger <python@rcn.com>
parents: 24471
diff changeset
1157 PyObject *ans;
b12e326b4ea2 Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
Raymond Hettinger <python@rcn.com>
parents: 24471
diff changeset
1158
26818
e094a03a80ff SF patch #659536: Use PyArg_UnpackTuple where possible.
Raymond Hettinger <python@rcn.com>
parents: 26661
diff changeset
1159 if (!PyArg_UnpackTuple(args, "log", 1, 2, &arg, &base))
26661
b12e326b4ea2 Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
Raymond Hettinger <python@rcn.com>
parents: 24471
diff changeset
1160 return NULL;
b12e326b4ea2 Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
Raymond Hettinger <python@rcn.com>
parents: 24471
diff changeset
1161
50122
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
1162 num = loghelper(arg, m_log, "log");
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1163 if (num == NULL || base == NULL)
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1164 return num;
26661
b12e326b4ea2 Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
Raymond Hettinger <python@rcn.com>
parents: 24471
diff changeset
1165
50122
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
1166 den = loghelper(base, m_log, "log");
26661
b12e326b4ea2 Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
Raymond Hettinger <python@rcn.com>
parents: 24471
diff changeset
1167 if (den == NULL) {
b12e326b4ea2 Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
Raymond Hettinger <python@rcn.com>
parents: 24471
diff changeset
1168 Py_DECREF(num);
b12e326b4ea2 Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
Raymond Hettinger <python@rcn.com>
parents: 24471
diff changeset
1169 return NULL;
b12e326b4ea2 Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
Raymond Hettinger <python@rcn.com>
parents: 24471
diff changeset
1170 }
b12e326b4ea2 Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
Raymond Hettinger <python@rcn.com>
parents: 24471
diff changeset
1171
b12e326b4ea2 Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
Raymond Hettinger <python@rcn.com>
parents: 24471
diff changeset
1172 ans = PyNumber_Divide(num, den);
b12e326b4ea2 Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
Raymond Hettinger <python@rcn.com>
parents: 24471
diff changeset
1173 Py_DECREF(num);
b12e326b4ea2 Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
Raymond Hettinger <python@rcn.com>
parents: 24471
diff changeset
1174 Py_DECREF(den);
b12e326b4ea2 Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
Raymond Hettinger <python@rcn.com>
parents: 24471
diff changeset
1175 return ans;
19713
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1176 }
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1177
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
1178 PyDoc_STRVAR(math_log_doc,
56977
7e02371aa506 Use a single style for all the docstrings in the math module.
Georg Brandl <georg@python.org>
parents: 56974
diff changeset
1179 "log(x[, base])\n\n\
7e02371aa506 Use a single style for all the docstrings in the math module.
Georg Brandl <georg@python.org>
parents: 56974
diff changeset
1180 Return the logarithm of x to the given base.\n\
26661
b12e326b4ea2 Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
Raymond Hettinger <python@rcn.com>
parents: 24471
diff changeset
1181 If the base not specified, returns the natural logarithm (base e) of x.");
19713
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1182
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1183 static PyObject *
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1184 math_log10(PyObject *self, PyObject *arg)
19713
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1185 {
50122
776a6cafc21a Merged revisions 67707 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48102
diff changeset
1186 return loghelper(arg, m_log10, "log10");
19713
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1187 }
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1188
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
1189 PyDoc_STRVAR(math_log10_doc,
56977
7e02371aa506 Use a single style for all the docstrings in the math module.
Georg Brandl <georg@python.org>
parents: 56974
diff changeset
1190 "log10(x)\n\nReturn the base 10 logarithm of x.");
19713
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1191
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1192 static PyObject *
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1193 math_fmod(PyObject *self, PyObject *args)
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1194 {
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1195 PyObject *ox, *oy;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1196 double r, x, y;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1197 if (! PyArg_UnpackTuple(args, "fmod", 2, 2, &ox, &oy))
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1198 return NULL;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1199 x = PyFloat_AsDouble(ox);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1200 y = PyFloat_AsDouble(oy);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1201 if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1202 return NULL;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1203 /* fmod(x, +/-Inf) returns x for finite x. */
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1204 if (Py_IS_INFINITY(y) && Py_IS_FINITE(x))
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1205 return PyFloat_FromDouble(x);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1206 errno = 0;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1207 PyFPE_START_PROTECT("in math_fmod", return 0);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1208 r = fmod(x, y);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1209 PyFPE_END_PROTECT(r);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1210 if (Py_IS_NAN(r)) {
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1211 if (!Py_IS_NAN(x) && !Py_IS_NAN(y))
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1212 errno = EDOM;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1213 else
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1214 errno = 0;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1215 }
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1216 if (errno && is_error(r))
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1217 return NULL;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1218 else
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1219 return PyFloat_FromDouble(r);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1220 }
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1221
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1222 PyDoc_STRVAR(math_fmod_doc,
56977
7e02371aa506 Use a single style for all the docstrings in the math module.
Georg Brandl <georg@python.org>
parents: 56974
diff changeset
1223 "fmod(x, y)\n\nReturn fmod(x, y), according to platform C."
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1224 " x % y may differ.");
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1225
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1226 static PyObject *
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1227 math_hypot(PyObject *self, PyObject *args)
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1228 {
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1229 PyObject *ox, *oy;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1230 double r, x, y;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1231 if (! PyArg_UnpackTuple(args, "hypot", 2, 2, &ox, &oy))
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1232 return NULL;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1233 x = PyFloat_AsDouble(ox);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1234 y = PyFloat_AsDouble(oy);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1235 if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1236 return NULL;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1237 /* hypot(x, +/-Inf) returns Inf, even if x is a NaN. */
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1238 if (Py_IS_INFINITY(x))
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1239 return PyFloat_FromDouble(fabs(x));
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1240 if (Py_IS_INFINITY(y))
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1241 return PyFloat_FromDouble(fabs(y));
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1242 errno = 0;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1243 PyFPE_START_PROTECT("in math_hypot", return 0);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1244 r = hypot(x, y);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1245 PyFPE_END_PROTECT(r);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1246 if (Py_IS_NAN(r)) {
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1247 if (!Py_IS_NAN(x) && !Py_IS_NAN(y))
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1248 errno = EDOM;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1249 else
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1250 errno = 0;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1251 }
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1252 else if (Py_IS_INFINITY(r)) {
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1253 if (Py_IS_FINITE(x) && Py_IS_FINITE(y))
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1254 errno = ERANGE;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1255 else
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1256 errno = 0;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1257 }
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1258 if (errno && is_error(r))
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1259 return NULL;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1260 else
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1261 return PyFloat_FromDouble(r);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1262 }
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1263
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1264 PyDoc_STRVAR(math_hypot_doc,
56977
7e02371aa506 Use a single style for all the docstrings in the math module.
Georg Brandl <georg@python.org>
parents: 56974
diff changeset
1265 "hypot(x, y)\n\nReturn the Euclidean distance, sqrt(x*x + y*y).");
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1266
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1267 /* pow can't use math_2, but needs its own wrapper: the problem is
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1268 that an infinite result can arise either as a result of overflow
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1269 (in which case OverflowError should be raised) or as a result of
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1270 e.g. 0.**-5. (for which ValueError needs to be raised.)
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1271 */
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1272
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1273 static PyObject *
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1274 math_pow(PyObject *self, PyObject *args)
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1275 {
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1276 PyObject *ox, *oy;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1277 double r, x, y;
46500
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1278 int odd_y;
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1279
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1280 if (! PyArg_UnpackTuple(args, "pow", 2, 2, &ox, &oy))
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1281 return NULL;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1282 x = PyFloat_AsDouble(ox);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1283 y = PyFloat_AsDouble(oy);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1284 if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1285 return NULL;
46490
648b4d01cccf Additional special-case handling for math.pow.
Mark Dickinson <dickinsm@gmail.com>
parents: 46486
diff changeset
1286
46500
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1287 /* deal directly with IEEE specials, to cope with problems on various
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1288 platforms whose semantics don't exactly match C99 */
46509
052fd8f1ca37 Silence 'r may be used uninitialized' compiler warning.
Mark Dickinson <dickinsm@gmail.com>
parents: 46507
diff changeset
1289 r = 0.; /* silence compiler warning */
46500
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1290 if (!Py_IS_FINITE(x) || !Py_IS_FINITE(y)) {
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1291 errno = 0;
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1292 if (Py_IS_NAN(x))
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1293 r = y == 0. ? 1. : x; /* NaN**0 = 1 */
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1294 else if (Py_IS_NAN(y))
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1295 r = x == 1. ? 1. : y; /* 1**NaN = 1 */
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1296 else if (Py_IS_INFINITY(x)) {
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1297 odd_y = Py_IS_FINITE(y) && fmod(fabs(y), 2.0) == 1.0;
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1298 if (y > 0.)
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1299 r = odd_y ? x : fabs(x);
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1300 else if (y == 0.)
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1301 r = 1.;
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1302 else /* y < 0. */
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1303 r = odd_y ? copysign(0., x) : 0.;
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1304 }
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1305 else if (Py_IS_INFINITY(y)) {
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1306 if (fabs(x) == 1.0)
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1307 r = 1.;
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1308 else if (y > 0. && fabs(x) > 1.0)
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1309 r = y;
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1310 else if (y < 0. && fabs(x) < 1.0) {
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1311 r = -y; /* result is +inf */
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1312 if (x == 0.) /* 0**-inf: divide-by-zero */
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1313 errno = EDOM;
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1314 }
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1315 else
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1316 r = 0.;
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1317 }
46486
82d85a05923b Additional tests for math.pow, and extra special-case
Mark Dickinson <dickinsm@gmail.com>
parents: 46473
diff changeset
1318 }
46500
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1319 else {
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1320 /* let libm handle finite**finite */
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1321 errno = 0;
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1322 PyFPE_START_PROTECT("in math_pow", return 0);
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1323 r = pow(x, y);
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1324 PyFPE_END_PROTECT(r);
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1325 /* a NaN result should arise only from (-ve)**(finite
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1326 non-integer); in this case we want to raise ValueError. */
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1327 if (!Py_IS_FINITE(r)) {
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1328 if (Py_IS_NAN(r)) {
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1329 errno = EDOM;
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1330 }
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1331 /*
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1332 an infinite result here arises either from:
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1333 (A) (+/-0.)**negative (-> divide-by-zero)
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1334 (B) overflow of x**y with x and y finite
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1335 */
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1336 else if (Py_IS_INFINITY(r)) {
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1337 if (x == 0.)
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1338 errno = EDOM;
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1339 else
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1340 errno = ERANGE;
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1341 }
a20def0101de Yet more explicit special case handling to make
Mark Dickinson <dickinsm@gmail.com>
parents: 46499
diff changeset
1342 }
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1343 }
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1344
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1345 if (errno && is_error(r))
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1346 return NULL;
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1347 else
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1348 return PyFloat_FromDouble(r);
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1349 }
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1350
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1351 PyDoc_STRVAR(math_pow_doc,
56977
7e02371aa506 Use a single style for all the docstrings in the math module.
Georg Brandl <georg@python.org>
parents: 56974
diff changeset
1352 "pow(x, y)\n\nReturn x**y (x to the power of y).");
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1353
44437
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1354 static const double degToRad = Py_MATH_PI / 180.0;
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1355 static const double radToDeg = 180.0 / Py_MATH_PI;
23427
a4d675b8b53c Added degrees() and radians() to mathmodule. Closes patch 552452 and
Raymond Hettinger <python@rcn.com>
parents: 19758
diff changeset
1356
a4d675b8b53c Added degrees() and radians() to mathmodule. Closes patch 552452 and
Raymond Hettinger <python@rcn.com>
parents: 19758
diff changeset
1357 static PyObject *
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1358 math_degrees(PyObject *self, PyObject *arg)
23427
a4d675b8b53c Added degrees() and radians() to mathmodule. Closes patch 552452 and
Raymond Hettinger <python@rcn.com>
parents: 19758
diff changeset
1359 {
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1360 double x = PyFloat_AsDouble(arg);
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1361 if (x == -1.0 && PyErr_Occurred())
23427
a4d675b8b53c Added degrees() and radians() to mathmodule. Closes patch 552452 and
Raymond Hettinger <python@rcn.com>
parents: 19758
diff changeset
1362 return NULL;
44437
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1363 return PyFloat_FromDouble(x * radToDeg);
23427
a4d675b8b53c Added degrees() and radians() to mathmodule. Closes patch 552452 and
Raymond Hettinger <python@rcn.com>
parents: 19758
diff changeset
1364 }
a4d675b8b53c Added degrees() and radians() to mathmodule. Closes patch 552452 and
Raymond Hettinger <python@rcn.com>
parents: 19758
diff changeset
1365
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
1366 PyDoc_STRVAR(math_degrees_doc,
56977
7e02371aa506 Use a single style for all the docstrings in the math module.
Georg Brandl <georg@python.org>
parents: 56974
diff changeset
1367 "degrees(x)\n\n\
7e02371aa506 Use a single style for all the docstrings in the math module.
Georg Brandl <georg@python.org>
parents: 56974
diff changeset
1368 Convert angle x from radians to degrees.");
23427
a4d675b8b53c Added degrees() and radians() to mathmodule. Closes patch 552452 and
Raymond Hettinger <python@rcn.com>
parents: 19758
diff changeset
1369
a4d675b8b53c Added degrees() and radians() to mathmodule. Closes patch 552452 and
Raymond Hettinger <python@rcn.com>
parents: 19758
diff changeset
1370 static PyObject *
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1371 math_radians(PyObject *self, PyObject *arg)
23427
a4d675b8b53c Added degrees() and radians() to mathmodule. Closes patch 552452 and
Raymond Hettinger <python@rcn.com>
parents: 19758
diff changeset
1372 {
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1373 double x = PyFloat_AsDouble(arg);
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1374 if (x == -1.0 && PyErr_Occurred())
23427
a4d675b8b53c Added degrees() and radians() to mathmodule. Closes patch 552452 and
Raymond Hettinger <python@rcn.com>
parents: 19758
diff changeset
1375 return NULL;
a4d675b8b53c Added degrees() and radians() to mathmodule. Closes patch 552452 and
Raymond Hettinger <python@rcn.com>
parents: 19758
diff changeset
1376 return PyFloat_FromDouble(x * degToRad);
a4d675b8b53c Added degrees() and radians() to mathmodule. Closes patch 552452 and
Raymond Hettinger <python@rcn.com>
parents: 19758
diff changeset
1377 }
a4d675b8b53c Added degrees() and radians() to mathmodule. Closes patch 552452 and
Raymond Hettinger <python@rcn.com>
parents: 19758
diff changeset
1378
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
1379 PyDoc_STRVAR(math_radians_doc,
56977
7e02371aa506 Use a single style for all the docstrings in the math module.
Georg Brandl <georg@python.org>
parents: 56974
diff changeset
1380 "radians(x)\n\n\
7e02371aa506 Use a single style for all the docstrings in the math module.
Georg Brandl <georg@python.org>
parents: 56974
diff changeset
1381 Convert angle x from degrees to radians.");
19713
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1382
44437
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1383 static PyObject *
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1384 math_isnan(PyObject *self, PyObject *arg)
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1385 {
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1386 double x = PyFloat_AsDouble(arg);
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1387 if (x == -1.0 && PyErr_Occurred())
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1388 return NULL;
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1389 return PyBool_FromLong((long)Py_IS_NAN(x));
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1390 }
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1391
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1392 PyDoc_STRVAR(math_isnan_doc,
56977
7e02371aa506 Use a single style for all the docstrings in the math module.
Georg Brandl <georg@python.org>
parents: 56974
diff changeset
1393 "isnan(x) -> bool\n\n\
7e02371aa506 Use a single style for all the docstrings in the math module.
Georg Brandl <georg@python.org>
parents: 56974
diff changeset
1394 Check if float x is not a number (NaN).");
44437
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1395
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1396 static PyObject *
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1397 math_isinf(PyObject *self, PyObject *arg)
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1398 {
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1399 double x = PyFloat_AsDouble(arg);
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1400 if (x == -1.0 && PyErr_Occurred())
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1401 return NULL;
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1402 return PyBool_FromLong((long)Py_IS_INFINITY(x));
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1403 }
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1404
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1405 PyDoc_STRVAR(math_isinf_doc,
56977
7e02371aa506 Use a single style for all the docstrings in the math module.
Georg Brandl <georg@python.org>
parents: 56974
diff changeset
1406 "isinf(x) -> bool\n\n\
7e02371aa506 Use a single style for all the docstrings in the math module.
Georg Brandl <georg@python.org>
parents: 56974
diff changeset
1407 Check if float x is infinite (positive or negative).");
44437
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1408
4635
49745ddb4f69 Renamed
Barry Warsaw <barry@python.org>
parents: 4503
diff changeset
1409 static PyMethodDef math_methods[] = {
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1410 {"acos", math_acos, METH_O, math_acos_doc},
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1411 {"acosh", math_acosh, METH_O, math_acosh_doc},
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1412 {"asin", math_asin, METH_O, math_asin_doc},
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1413 {"asinh", math_asinh, METH_O, math_asinh_doc},
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1414 {"atan", math_atan, METH_O, math_atan_doc},
13326
24717405dd89 ANSI-fication, remove Py_PROTO, etc.
Fred Drake <fdrake@acm.org>
parents: 13309
diff changeset
1415 {"atan2", math_atan2, METH_VARARGS, math_atan2_doc},
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1416 {"atanh", math_atanh, METH_O, math_atanh_doc},
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1417 {"ceil", math_ceil, METH_O, math_ceil_doc},
44440
6208b17d0dbe Added copysign(x, y) function to the math module
Christian Heimes <christian@cheimes.de>
parents: 44437
diff changeset
1418 {"copysign", math_copysign, METH_VARARGS, math_copysign_doc},
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1419 {"cos", math_cos, METH_O, math_cos_doc},
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1420 {"cosh", math_cosh, METH_O, math_cosh_doc},
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1421 {"degrees", math_degrees, METH_O, math_degrees_doc},
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1422 {"exp", math_exp, METH_O, math_exp_doc},
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1423 {"fabs", math_fabs, METH_O, math_fabs_doc},
47529
6428c4f1ae09 Issue #2138: Add math.factorial().
Raymond Hettinger <python@rcn.com>
parents: 47395
diff changeset
1424 {"factorial", math_factorial, METH_O, math_factorial_doc},
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1425 {"floor", math_floor, METH_O, math_floor_doc},
13326
24717405dd89 ANSI-fication, remove Py_PROTO, etc.
Fred Drake <fdrake@acm.org>
parents: 13309
diff changeset
1426 {"fmod", math_fmod, METH_VARARGS, math_fmod_doc},
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1427 {"frexp", math_frexp, METH_O, math_frexp_doc},
48101
8d05dda735f8 Rename math.sum to math.fsum
Mark Dickinson <dickinsm@gmail.com>
parents: 48099
diff changeset
1428 {"fsum", math_fsum, METH_O, math_fsum_doc},
56268
b50dd17dfe26 Issue #3366: Add gamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 50243
diff changeset
1429 {"gamma", math_gamma, METH_O, math_gamma_doc},
13326
24717405dd89 ANSI-fication, remove Py_PROTO, etc.
Fred Drake <fdrake@acm.org>
parents: 13309
diff changeset
1430 {"hypot", math_hypot, METH_VARARGS, math_hypot_doc},
44437
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1431 {"isinf", math_isinf, METH_O, math_isinf_doc},
968bda81e6c8 Added math.isinf() and math.isnan()
Christian Heimes <christian@cheimes.de>
parents: 44432
diff changeset
1432 {"isnan", math_isnan, METH_O, math_isnan_doc},
13326
24717405dd89 ANSI-fication, remove Py_PROTO, etc.
Fred Drake <fdrake@acm.org>
parents: 13309
diff changeset
1433 {"ldexp", math_ldexp, METH_VARARGS, math_ldexp_doc},
57655
cb22eaee86c9 Issue #3366: Add lgamma function to math module.
Mark Dickinson <dickinsm@gmail.com>
parents: 56977
diff changeset
1434 {"lgamma", math_lgamma, METH_O, math_lgamma_doc},
13326
24717405dd89 ANSI-fication, remove Py_PROTO, etc.
Fred Drake <fdrake@acm.org>
parents: 13309
diff changeset
1435 {"log", math_log, METH_VARARGS, math_log_doc},
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1436 {"log1p", math_log1p, METH_O, math_log1p_doc},
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1437 {"log10", math_log10, METH_O, math_log10_doc},
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1438 {"modf", math_modf, METH_O, math_modf_doc},
13326
24717405dd89 ANSI-fication, remove Py_PROTO, etc.
Fred Drake <fdrake@acm.org>
parents: 13309
diff changeset
1439 {"pow", math_pow, METH_VARARGS, math_pow_doc},
40362
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1440 {"radians", math_radians, METH_O, math_radians_doc},
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1441 {"sin", math_sin, METH_O, math_sin_doc},
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1442 {"sinh", math_sinh, METH_O, math_sinh_doc},
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1443 {"sqrt", math_sqrt, METH_O, math_sqrt_doc},
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1444 {"tan", math_tan, METH_O, math_tan_doc},
271133981e63 Speed up function calls into the math module by using METH_O.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38491
diff changeset
1445 {"tanh", math_tanh, METH_O, math_tanh_doc},
48101
8d05dda735f8 Rename math.sum to math.fsum
Mark Dickinson <dickinsm@gmail.com>
parents: 48099
diff changeset
1446 {"trunc", math_trunc, METH_O, math_trunc_doc},
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1447 {NULL, NULL} /* sentinel */
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1448 };
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1449
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
1450
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
1451 PyDoc_STRVAR(module_doc,
19712
b4521436e8f8 Mechanical fiddling to make this easier to work with in my editor.
Tim Peters <tim.peters@gmail.com>
parents: 19048
diff changeset
1452 "This module is always available. It provides access to the\n"
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
1453 "mathematical functions defined by the C standard.");
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
1454
24471
f66b3a3509c7 Excise DL_EXPORT/DL_IMPORT from Modules/*. Required adding a prototype
Mark Hammond <mhammond@skippinet.com.au>
parents: 23832
diff changeset
1455 PyMODINIT_FUNC
13651
8a063423e0b7 Bunch of minor ANSIfications: 'void initfunc()' -> 'void initfunc(void)',
Thomas Wouters <thomas@python.org>
parents: 13331
diff changeset
1456 initmath(void)
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1457 {
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1458 PyObject *m;
19048
e282d6b2b758 Part of SF patch [#431848] mathmodule.c: doc strings & conversion, from
Tim Peters <tim.peters@gmail.com>
parents: 18066
diff changeset
1459
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
1460 m = Py_InitModule3("math", math_methods, module_doc);
36324
1af7f719ed28 Check return result from Py_InitModule*(). This API can fail.
Neal Norwitz <nnorwitz@gmail.com>
parents: 34872
diff changeset
1461 if (m == NULL)
1af7f719ed28 Check return result from Py_InitModule*(). This API can fail.
Neal Norwitz <nnorwitz@gmail.com>
parents: 34872
diff changeset
1462 goto finally;
4752
7367fb107108 Better error checking in initmath().
Barry Warsaw <barry@python.org>
parents: 4635
diff changeset
1463
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1464 PyModule_AddObject(m, "pi", PyFloat_FromDouble(Py_MATH_PI));
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1465 PyModule_AddObject(m, "e", PyFloat_FromDouble(Py_MATH_E));
4752
7367fb107108 Better error checking in initmath().
Barry Warsaw <barry@python.org>
parents: 4635
diff changeset
1466
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 45102
diff changeset
1467 finally:
14346
5397fdf88ec2 Do the absolute minimal amount of modifications to eradicate
Barry Warsaw <barry@python.org>
parents: 13912
diff changeset
1468 return;
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1469 }