annotate Modules/mathmodule.c @ 58664:993f703a61ba

Merged revisions 77484,77487,77561,77570,77593,77603,77608,77667,77702-77703,77739,77858,77887,77889 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r77484 | skip.montanaro | 2010-01-13 19:12:34 -0600 (Wed, 13 Jan 2010) | 4 lines Update PyEval_EvalFrame to PyEval_EvalFrameEx. This looks to have been done partially before. Also add a comment describing how this might have to work with different versions of the interpreter. ........ r77487 | ezio.melotti | 2010-01-14 05:34:10 -0600 (Thu, 14 Jan 2010) | 1 line Fixed typo ........ r77561 | georg.brandl | 2010-01-17 02:42:30 -0600 (Sun, 17 Jan 2010) | 1 line #7699: improve datetime docs: straightforward linking to strftime/strptime section, mark classmethods as such. ........ r77570 | georg.brandl | 2010-01-17 06:14:42 -0600 (Sun, 17 Jan 2010) | 1 line Add note about usage of STRINGLIB_EMPTY. ........ r77593 | georg.brandl | 2010-01-17 17:33:53 -0600 (Sun, 17 Jan 2010) | 1 line Fix internal reference. ........ r77603 | benjamin.peterson | 2010-01-18 17:07:56 -0600 (Mon, 18 Jan 2010) | 8 lines data descriptors do not override the class dictionary if __get__ is not defined Adjust documentation and add a test to verify this behavior. See http://mail.python.org/pipermail/python-dev/2010-January/095637.html for discussion. ........ r77608 | gregory.p.smith | 2010-01-19 02:19:03 -0600 (Tue, 19 Jan 2010) | 6 lines Do not compile stubs for the sha2 series hashes in the openssl hashlib module when the openssl version is too old to support them. That leads both compiled code bloat and to unittests attempting to test implementations that don't exist for comparison purposes on such platforms. ........ r77667 | mark.dickinson | 2010-01-21 12:32:27 -0600 (Thu, 21 Jan 2010) | 1 line Add two more test_strtod test values. ........ r77702 | georg.brandl | 2010-01-23 02:43:31 -0600 (Sat, 23 Jan 2010) | 1 line #7762: fix refcount annotation of PyUnicode_Tailmatch(). ........ r77703 | georg.brandl | 2010-01-23 02:47:54 -0600 (Sat, 23 Jan 2010) | 1 line #7725: fix referencing issue. ........ r77739 | benjamin.peterson | 2010-01-24 21:52:52 -0600 (Sun, 24 Jan 2010) | 1 line mention from_float() in error message ........ r77858 | georg.brandl | 2010-01-30 11:57:48 -0600 (Sat, 30 Jan 2010) | 1 line #7802: fix invalid example (heh). ........ r77887 | georg.brandl | 2010-01-31 12:51:49 -0600 (Sun, 31 Jan 2010) | 5 lines Fix-up ftplib documentation: move exception descriptions to toplevel, not inside a class remove attribution in "versionadded" spell and grammar check docstring of FTP_TLS ........ r77889 | michael.foord | 2010-01-31 13:59:26 -0600 (Sun, 31 Jan 2010) | 1 line Minor modification to unittest documentation. ........
author Benjamin Peterson <benjamin@python.org>
date Wed, 03 Feb 2010 02:35:45 +0000
parents 9b9adc42c73a
children cab14be0ada1
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
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
3 /* Here are some comments from Tim Peters, extracted from the
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
4 discussion attached to http://bugs.python.org/issue1640. They
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
5 describe the general aims of the math module with respect to
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
6 special values, IEEE-754 floating-point exceptions, and Python
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
7 exceptions.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
8
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
9 These are the "spirit of 754" rules:
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
10
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
11 1. If the mathematical result is a real number, but of magnitude too
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
12 large to approximate by a machine float, overflow is signaled and the
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
13 result is an infinity (with the appropriate sign).
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
14
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
15 2. If the mathematical result is a real number, but of magnitude too
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
16 small to approximate by a machine float, underflow is signaled and the
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
17 result is a zero (with the appropriate sign).
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
18
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
19 3. At a singularity (a value x such that the limit of f(y) as y
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
20 approaches x exists and is an infinity), "divide by zero" is signaled
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
21 and the result is an infinity (with the appropriate sign). This is
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
22 complicated a little by that the left-side and right-side limits may
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
23 not be the same; e.g., 1/x approaches +inf or -inf as x approaches 0
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
24 from the positive or negative directions. In that specific case, the
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
25 sign of the zero determines the result of 1/0.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
26
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
27 4. At a point where a function has no defined result in the extended
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
28 reals (i.e., the reals plus an infinity or two), invalid operation is
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
29 signaled and a NaN is returned.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
30
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
31 And these are what Python has historically /tried/ to do (but not
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
32 always successfully, as platform libm behavior varies a lot):
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
33
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
34 For #1, raise OverflowError.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
35
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
36 For #2, return a zero (with the appropriate sign if that happens by
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
37 accident ;-)).
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
38
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
39 For #3 and #4, raise ValueError. It may have made sense to raise
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
40 Python's ZeroDivisionError in #3, but historically that's only been
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
41 raised for division by zero and mod by zero.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
42
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
43 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
44
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
45 /*
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
46 In general, on an IEEE-754 platform the aim is to follow the C99
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
47 standard, including Annex 'F', whenever possible. Where the
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
48 standard recommends raising the 'divide-by-zero' or 'invalid'
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
49 floating-point exceptions, Python should raise a ValueError. Where
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
50 the standard recommends raising 'overflow', Python should raise an
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
51 OverflowError. In all other circumstances a value should be
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
52 returned.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
53 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
54
4635
49745ddb4f69 Renamed
Barry Warsaw <barry@python.org>
parents: 4503
diff changeset
55 #include "Python.h"
57758
b45ca11b9a3e Merged revisions 76861 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57660
diff changeset
56 #include "_math.h"
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
57
44943
6547be11f443 Merged revisions 60245-60277 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44499
diff changeset
58 #ifdef _OSF_SOURCE
6547be11f443 Merged revisions 60245-60277 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44499
diff changeset
59 /* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */
6547be11f443 Merged revisions 60245-60277 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44499
diff changeset
60 extern double copysign(double, double);
6547be11f443 Merged revisions 60245-60277 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44499
diff changeset
61 #endif
6547be11f443 Merged revisions 60245-60277 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44499
diff changeset
62
56270
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
63 /*
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
64 sin(pi*x), giving accurate results for all finite x (especially x
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
65 integral or close to an integer). This is here for use in the
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
66 reflection formula for the gamma function. It conforms to IEEE
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
67 754-2008 for finite arguments, but not for infinities or nans.
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
68 */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
69
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
70 static const double pi = 3.141592653589793238462643383279502884197;
57770
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
71 static const double sqrtpi = 1.772453850905516027298167483341145182798;
56270
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
72
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
73 static double
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
74 sinpi(double x)
498
56bb1067a880 Improve error handling.
Guido van Rossum <guido@python.org>
parents: 438
diff changeset
75 {
56270
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
76 double y, r;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
77 int n;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
78 /* this function should only ever be called for finite arguments */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
79 assert(Py_IS_FINITE(x));
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
80 y = fmod(fabs(x), 2.0);
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
81 n = (int)round(2.0*y);
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
82 assert(0 <= n && n <= 4);
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
83 switch (n) {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
84 case 0:
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
85 r = sin(pi*y);
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
86 break;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
87 case 1:
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
88 r = cos(pi*(y-0.5));
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
89 break;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
90 case 2:
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
91 /* N.B. -sin(pi*(y-1.0)) is *not* equivalent: it would give
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
92 -0.0 instead of 0.0 when y == 1.0. */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
93 r = sin(pi*(1.0-y));
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
94 break;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
95 case 3:
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
96 r = -cos(pi*(y-1.5));
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
97 break;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
98 case 4:
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
99 r = sin(pi*(y-2.0));
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
100 break;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
101 default:
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
102 assert(0); /* should never get here */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
103 r = -1.23e200; /* silence gcc warning */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
104 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
105 return copysign(1.0, x)*r;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
106 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
107
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
108 /* Implementation of the real gamma function. In extensive but non-exhaustive
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
109 random tests, this function proved accurate to within <= 10 ulps across the
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
110 entire float domain. Note that accuracy may depend on the quality of the
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
111 system math functions, the pow function in particular. Special cases
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
112 follow C99 annex F. The parameters and method are tailored to platforms
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
113 whose double format is the IEEE 754 binary64 format.
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
114
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
115 Method: for x > 0.0 we use the Lanczos approximation with parameters N=13
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
116 and g=6.024680040776729583740234375; these parameters are amongst those
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
117 used by the Boost library. Following Boost (again), we re-express the
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
118 Lanczos sum as a rational function, and compute it that way. The
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
119 coefficients below were computed independently using MPFR, and have been
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
120 double-checked against the coefficients in the Boost source code.
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
121
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
122 For x < 0.0 we use the reflection formula.
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
123
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
124 There's one minor tweak that deserves explanation: Lanczos' formula for
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
125 Gamma(x) involves computing pow(x+g-0.5, x-0.5) / exp(x+g-0.5). For many x
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
126 values, x+g-0.5 can be represented exactly. However, in cases where it
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
127 can't be represented exactly the small error in x+g-0.5 can be magnified
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
128 significantly by the pow and exp calls, especially for large x. A cheap
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
129 correction is to multiply by (1 + e*g/(x+g-0.5)), where e is the error
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
130 involved in the computation of x+g-0.5 (that is, e = computed value of
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
131 x+g-0.5 - exact value of x+g-0.5). Here's the proof:
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
132
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
133 Correction factor
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
134 -----------------
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
135 Write x+g-0.5 = y-e, where y is exactly representable as an IEEE 754
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
136 double, and e is tiny. Then:
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
137
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
138 pow(x+g-0.5,x-0.5)/exp(x+g-0.5) = pow(y-e, x-0.5)/exp(y-e)
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
139 = pow(y, x-0.5)/exp(y) * C,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
140
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
141 where the correction_factor C is given by
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
142
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
143 C = pow(1-e/y, x-0.5) * exp(e)
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
144
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
145 Since e is tiny, pow(1-e/y, x-0.5) ~ 1-(x-0.5)*e/y, and exp(x) ~ 1+e, so:
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
146
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
147 C ~ (1-(x-0.5)*e/y) * (1+e) ~ 1 + e*(y-(x-0.5))/y
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
148
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
149 But y-(x-0.5) = g+e, and g+e ~ g. So we get C ~ 1 + e*g/y, and
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
150
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
151 pow(x+g-0.5,x-0.5)/exp(x+g-0.5) ~ pow(y, x-0.5)/exp(y) * (1 + e*g/y),
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
152
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
153 Note that for accuracy, when computing r*C it's better to do
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
154
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
155 r + e*g/y*r;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
156
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
157 than
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
158
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
159 r * (1 + e*g/y);
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
160
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
161 since the addition in the latter throws away most of the bits of
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
162 information in e*g/y.
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
163 */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
164
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
165 #define LANCZOS_N 13
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
166 static const double lanczos_g = 6.024680040776729583740234375;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
167 static const double lanczos_g_minus_half = 5.524680040776729583740234375;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
168 static const double lanczos_num_coeffs[LANCZOS_N] = {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
169 23531376880.410759688572007674451636754734846804940,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
170 42919803642.649098768957899047001988850926355848959,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
171 35711959237.355668049440185451547166705960488635843,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
172 17921034426.037209699919755754458931112671403265390,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
173 6039542586.3520280050642916443072979210699388420708,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
174 1439720407.3117216736632230727949123939715485786772,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
175 248874557.86205415651146038641322942321632125127801,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
176 31426415.585400194380614231628318205362874684987640,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
177 2876370.6289353724412254090516208496135991145378768,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
178 186056.26539522349504029498971604569928220784236328,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
179 8071.6720023658162106380029022722506138218516325024,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
180 210.82427775157934587250973392071336271166969580291,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
181 2.5066282746310002701649081771338373386264310793408
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
182 };
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
183
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
184 /* denominator is x*(x+1)*...*(x+LANCZOS_N-2) */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
185 static const double lanczos_den_coeffs[LANCZOS_N] = {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
186 0.0, 39916800.0, 120543840.0, 150917976.0, 105258076.0, 45995730.0,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
187 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
188
56270
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
189 /* gamma values for small positive integers, 1 though NGAMMA_INTEGRAL */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
190 #define NGAMMA_INTEGRAL 23
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
191 static const double gamma_integral[NGAMMA_INTEGRAL] = {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
192 1.0, 1.0, 2.0, 6.0, 24.0, 120.0, 720.0, 5040.0, 40320.0, 362880.0,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
193 3628800.0, 39916800.0, 479001600.0, 6227020800.0, 87178291200.0,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
194 1307674368000.0, 20922789888000.0, 355687428096000.0,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
195 6402373705728000.0, 121645100408832000.0, 2432902008176640000.0,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
196 51090942171709440000.0, 1124000727777607680000.0,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
197 };
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
198
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
199 /* Lanczos' sum L_g(x), for positive x */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
200
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
201 static double
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
202 lanczos_sum(double x)
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
203 {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
204 double num = 0.0, den = 0.0;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
205 int i;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
206 assert(x > 0.0);
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
207 /* evaluate the rational function lanczos_sum(x). For large
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
208 x, the obvious algorithm risks overflow, so we instead
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
209 rescale the denominator and numerator of the rational
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
210 function by x**(1-LANCZOS_N) and treat this as a
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
211 rational function in 1/x. This also reduces the error for
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
212 larger x values. The choice of cutoff point (5.0 below) is
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
213 somewhat arbitrary; in tests, smaller cutoff values than
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
214 this resulted in lower accuracy. */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
215 if (x < 5.0) {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
216 for (i = LANCZOS_N; --i >= 0; ) {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
217 num = num * x + lanczos_num_coeffs[i];
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
218 den = den * x + lanczos_den_coeffs[i];
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
219 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
220 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
221 else {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
222 for (i = 0; i < LANCZOS_N; i++) {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
223 num = num / x + lanczos_num_coeffs[i];
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
224 den = den / x + lanczos_den_coeffs[i];
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
225 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
226 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
227 return num/den;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
228 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
229
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
230 static double
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
231 m_tgamma(double x)
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
232 {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
233 double absx, r, y, z, sqrtpow;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
234
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
235 /* special cases */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
236 if (!Py_IS_FINITE(x)) {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
237 if (Py_IS_NAN(x) || x > 0.0)
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
238 return x; /* tgamma(nan) = nan, tgamma(inf) = inf */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
239 else {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
240 errno = EDOM;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
241 return Py_NAN; /* tgamma(-inf) = nan, invalid */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
242 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
243 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
244 if (x == 0.0) {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
245 errno = EDOM;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
246 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
247 }
56270
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
248
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
249 /* integer arguments */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
250 if (x == floor(x)) {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
251 if (x < 0.0) {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
252 errno = EDOM; /* tgamma(n) = nan, invalid for */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
253 return Py_NAN; /* negative integers n */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
254 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
255 if (x <= NGAMMA_INTEGRAL)
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
256 return gamma_integral[(int)x - 1];
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
257 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
258 absx = fabs(x);
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
259
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
260 /* tiny arguments: tgamma(x) ~ 1/x for x near 0 */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
261 if (absx < 1e-20) {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
262 r = 1.0/x;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
263 if (Py_IS_INFINITY(r))
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
264 errno = ERANGE;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
265 return r;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
266 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
267
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
268 /* large arguments: assuming IEEE 754 doubles, tgamma(x) overflows for
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
269 x > 200, and underflows to +-0.0 for x < -200, not a negative
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
270 integer. */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
271 if (absx > 200.0) {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
272 if (x < 0.0) {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
273 return 0.0/sinpi(x);
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
274 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
275 else {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
276 errno = ERANGE;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
277 return Py_HUGE_VAL;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
278 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
279 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
280
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
281 y = absx + lanczos_g_minus_half;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
282 /* compute error in sum */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
283 if (absx > lanczos_g_minus_half) {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
284 /* note: the correction can be foiled by an optimizing
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
285 compiler that (incorrectly) thinks that an expression like
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
286 a + b - a - b can be optimized to 0.0. This shouldn't
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
287 happen in a standards-conforming compiler. */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
288 double q = y - absx;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
289 z = q - lanczos_g_minus_half;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
290 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
291 else {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
292 double q = y - lanczos_g_minus_half;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
293 z = q - absx;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
294 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
295 z = z * lanczos_g / y;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
296 if (x < 0.0) {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
297 r = -pi / sinpi(absx) / absx * exp(y) / lanczos_sum(absx);
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
298 r -= z * r;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
299 if (absx < 140.0) {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
300 r /= pow(y, absx - 0.5);
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
301 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
302 else {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
303 sqrtpow = pow(y, absx / 2.0 - 0.25);
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
304 r /= sqrtpow;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
305 r /= sqrtpow;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
306 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
307 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
308 else {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
309 r = lanczos_sum(absx) / exp(y);
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
310 r += z * r;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
311 if (absx < 140.0) {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
312 r *= pow(y, absx - 0.5);
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
313 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
314 else {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
315 sqrtpow = pow(y, absx / 2.0 - 0.25);
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
316 r *= sqrtpow;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
317 r *= sqrtpow;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
318 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
319 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
320 if (Py_IS_INFINITY(r))
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
321 errno = ERANGE;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
322 return r;
498
56bb1067a880 Improve error handling.
Guido van Rossum <guido@python.org>
parents: 438
diff changeset
323 }
56bb1067a880 Improve error handling.
Guido van Rossum <guido@python.org>
parents: 438
diff changeset
324
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
325 /*
57660
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
326 lgamma: natural log of the absolute value of the Gamma function.
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
327 For large arguments, Lanczos' formula works extremely well here.
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
328 */
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
329
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
330 static double
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
331 m_lgamma(double x)
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
332 {
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
333 double r, absx;
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
334
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
335 /* special cases */
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
336 if (!Py_IS_FINITE(x)) {
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
337 if (Py_IS_NAN(x))
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
338 return x; /* lgamma(nan) = nan */
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
339 else
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
340 return Py_HUGE_VAL; /* lgamma(+-inf) = +inf */
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
341 }
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
342
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
343 /* integer arguments */
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
344 if (x == floor(x) && x <= 2.0) {
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
345 if (x <= 0.0) {
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
346 errno = EDOM; /* lgamma(n) = inf, divide-by-zero for */
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
347 return Py_HUGE_VAL; /* integers n <= 0 */
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
348 }
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
349 else {
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
350 return 0.0; /* lgamma(1) = lgamma(2) = 0.0 */
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
351 }
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
352 }
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
353
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
354 absx = fabs(x);
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
355 /* tiny arguments: lgamma(x) ~ -log(fabs(x)) for small x */
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
356 if (absx < 1e-20)
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
357 return -log(absx);
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
358
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
359 /* Lanczos' formula */
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
360 if (x > 0.0) {
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
361 /* we could save a fraction of a ulp in accuracy by having a
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
362 second set of numerator coefficients for lanczos_sum that
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
363 absorbed the exp(-lanczos_g) term, and throwing out the
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
364 lanczos_g subtraction below; it's probably not worth it. */
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
365 r = log(lanczos_sum(x)) - lanczos_g +
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
366 (x-0.5)*(log(x+lanczos_g-0.5)-1);
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
367 }
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
368 else {
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
369 r = log(pi) - log(fabs(sinpi(absx))) - log(absx) -
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
370 (log(lanczos_sum(absx)) - lanczos_g +
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
371 (absx-0.5)*(log(absx+lanczos_g-0.5)-1));
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
372 }
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
373 if (Py_IS_INFINITY(r))
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
374 errno = ERANGE;
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
375 return r;
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
376 }
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
377
57770
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
378 /*
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
379 Implementations of the error function erf(x) and the complementary error
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
380 function erfc(x).
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
381
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
382 Method: following 'Numerical Recipes' by Flannery, Press et. al. (2nd ed.,
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
383 Cambridge University Press), we use a series approximation for erf for
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
384 small x, and a continued fraction approximation for erfc(x) for larger x;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
385 combined with the relations erf(-x) = -erf(x) and erfc(x) = 1.0 - erf(x),
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
386 this gives us erf(x) and erfc(x) for all x.
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
387
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
388 The series expansion used is:
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
389
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
390 erf(x) = x*exp(-x*x)/sqrt(pi) * [
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
391 2/1 + 4/3 x**2 + 8/15 x**4 + 16/105 x**6 + ...]
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
392
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
393 The coefficient of x**(2k-2) here is 4**k*factorial(k)/factorial(2*k).
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
394 This series converges well for smallish x, but slowly for larger x.
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
395
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
396 The continued fraction expansion used is:
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
397
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
398 erfc(x) = x*exp(-x*x)/sqrt(pi) * [1/(0.5 + x**2 -) 0.5/(2.5 + x**2 - )
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
399 3.0/(4.5 + x**2 - ) 7.5/(6.5 + x**2 - ) ...]
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
400
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
401 after the first term, the general term has the form:
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
402
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
403 k*(k-0.5)/(2*k+0.5 + x**2 - ...).
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
404
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
405 This expansion converges fast for larger x, but convergence becomes
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
406 infinitely slow as x approaches 0.0. The (somewhat naive) continued
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
407 fraction evaluation algorithm used below also risks overflow for large x;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
408 but for large x, erfc(x) == 0.0 to within machine precision. (For
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
409 example, erfc(30.0) is approximately 2.56e-393).
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
410
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
411 Parameters: use series expansion for abs(x) < ERF_SERIES_CUTOFF and
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
412 continued fraction expansion for ERF_SERIES_CUTOFF <= abs(x) <
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
413 ERFC_CONTFRAC_CUTOFF. ERFC_SERIES_TERMS and ERFC_CONTFRAC_TERMS are the
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
414 numbers of terms to use for the relevant expansions. */
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
415
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
416 #define ERF_SERIES_CUTOFF 1.5
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
417 #define ERF_SERIES_TERMS 25
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
418 #define ERFC_CONTFRAC_CUTOFF 30.0
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
419 #define ERFC_CONTFRAC_TERMS 50
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
420
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
421 /*
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
422 Error function, via power series.
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
423
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
424 Given a finite float x, return an approximation to erf(x).
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
425 Converges reasonably fast for small x.
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
426 */
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
427
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
428 static double
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
429 m_erf_series(double x)
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
430 {
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
431 double x2, acc, fk;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
432 int i;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
433
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
434 x2 = x * x;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
435 acc = 0.0;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
436 fk = (double)ERF_SERIES_TERMS + 0.5;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
437 for (i = 0; i < ERF_SERIES_TERMS; i++) {
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
438 acc = 2.0 + x2 * acc / fk;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
439 fk -= 1.0;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
440 }
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
441 return acc * x * exp(-x2) / sqrtpi;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
442 }
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
443
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
444 /*
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
445 Complementary error function, via continued fraction expansion.
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
446
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
447 Given a positive float x, return an approximation to erfc(x). Converges
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
448 reasonably fast for x large (say, x > 2.0), and should be safe from
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
449 overflow if x and nterms are not too large. On an IEEE 754 machine, with x
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
450 <= 30.0, we're safe up to nterms = 100. For x >= 30.0, erfc(x) is smaller
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
451 than the smallest representable nonzero float. */
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
452
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
453 static double
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
454 m_erfc_contfrac(double x)
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
455 {
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
456 double x2, a, da, p, p_last, q, q_last, b;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
457 int i;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
458
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
459 if (x >= ERFC_CONTFRAC_CUTOFF)
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
460 return 0.0;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
461
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
462 x2 = x*x;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
463 a = 0.0;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
464 da = 0.5;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
465 p = 1.0; p_last = 0.0;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
466 q = da + x2; q_last = 1.0;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
467 for (i = 0; i < ERFC_CONTFRAC_TERMS; i++) {
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
468 double temp;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
469 a += da;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
470 da += 2.0;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
471 b = da + x2;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
472 temp = p; p = b*p - a*p_last; p_last = temp;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
473 temp = q; q = b*q - a*q_last; q_last = temp;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
474 }
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
475 return p / q * x * exp(-x2) / sqrtpi;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
476 }
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
477
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
478 /* Error function erf(x), for general x */
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
479
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
480 static double
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
481 m_erf(double x)
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
482 {
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
483 double absx, cf;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
484
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
485 if (Py_IS_NAN(x))
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
486 return x;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
487 absx = fabs(x);
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
488 if (absx < ERF_SERIES_CUTOFF)
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
489 return m_erf_series(x);
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
490 else {
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
491 cf = m_erfc_contfrac(absx);
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
492 return x > 0.0 ? 1.0 - cf : cf - 1.0;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
493 }
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
494 }
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
495
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
496 /* Complementary error function erfc(x), for general x. */
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
497
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
498 static double
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
499 m_erfc(double x)
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
500 {
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
501 double absx, cf;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
502
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
503 if (Py_IS_NAN(x))
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
504 return x;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
505 absx = fabs(x);
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
506 if (absx < ERF_SERIES_CUTOFF)
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
507 return 1.0 - m_erf_series(x);
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
508 else {
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
509 cf = m_erfc_contfrac(absx);
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
510 return x > 0.0 ? cf : 2.0 - cf;
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
511 }
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
512 }
57660
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
513
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
514 /*
46516
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
515 wrapper for atan2 that deals directly with special cases before
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
516 delegating to the platform libm for the remaining cases. This
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
517 is necessary to get consistent behaviour across platforms.
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
518 Windows, FreeBSD and alpha Tru64 are amongst platforms that don't
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
519 always follow C99.
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
520 */
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
521
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
522 static double
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
523 m_atan2(double y, double x)
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
524 {
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
525 if (Py_IS_NAN(x) || Py_IS_NAN(y))
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
526 return Py_NAN;
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
527 if (Py_IS_INFINITY(y)) {
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
528 if (Py_IS_INFINITY(x)) {
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
529 if (copysign(1., x) == 1.)
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
530 /* atan2(+-inf, +inf) == +-pi/4 */
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
531 return copysign(0.25*Py_MATH_PI, y);
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
532 else
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
533 /* atan2(+-inf, -inf) == +-pi*3/4 */
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
534 return copysign(0.75*Py_MATH_PI, y);
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
535 }
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
536 /* atan2(+-inf, x) == +-pi/2 for finite x */
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
537 return copysign(0.5*Py_MATH_PI, y);
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
538 }
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
539 if (Py_IS_INFINITY(x) || y == 0.) {
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
540 if (copysign(1., x) == 1.)
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
541 /* atan2(+-y, +inf) = atan2(+-0, +x) = +-0. */
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
542 return copysign(0., y);
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
543 else
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
544 /* atan2(+-y, -inf) = atan2(+-0., -x) = +-pi. */
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
545 return copysign(Py_MATH_PI, y);
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
546 }
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
547 return atan2(y, x);
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
548 }
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
549
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
550 /*
50123
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
551 Various platforms (Solaris, OpenBSD) do nonstandard things for log(0),
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
552 log(-ve), log(NaN). Here are wrappers for log and log10 that deal with
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
553 special values directly, passing positive non-special values through to
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
554 the system log/log10.
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
555 */
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
556
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
557 static double
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
558 m_log(double x)
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
559 {
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
560 if (Py_IS_FINITE(x)) {
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
561 if (x > 0.0)
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
562 return log(x);
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
563 errno = EDOM;
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
564 if (x == 0.0)
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
565 return -Py_HUGE_VAL; /* log(0) = -inf */
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
566 else
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
567 return Py_NAN; /* log(-ve) = nan */
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
568 }
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
569 else if (Py_IS_NAN(x))
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
570 return x; /* log(nan) = nan */
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
571 else if (x > 0.0)
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
572 return x; /* log(inf) = inf */
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
573 else {
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
574 errno = EDOM;
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
575 return Py_NAN; /* log(-inf) = nan */
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
576 }
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
577 }
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
578
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
579 static double
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
580 m_log10(double x)
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
581 {
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
582 if (Py_IS_FINITE(x)) {
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
583 if (x > 0.0)
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
584 return log10(x);
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
585 errno = EDOM;
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
586 if (x == 0.0)
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
587 return -Py_HUGE_VAL; /* log10(0) = -inf */
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
588 else
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
589 return Py_NAN; /* log10(-ve) = nan */
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
590 }
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
591 else if (Py_IS_NAN(x))
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
592 return x; /* log10(nan) = nan */
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
593 else if (x > 0.0)
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
594 return x; /* log10(inf) = inf */
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
595 else {
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
596 errno = EDOM;
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
597 return Py_NAN; /* log10(-inf) = nan */
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
598 }
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
599 }
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
600
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
601
56270
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
602 /* Call is_error when errno != 0, and where x is the result libm
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
603 * returned. is_error will usually set up an exception and return
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
604 * true (1), but may return false (0) without setting up an exception.
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
605 */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
606 static int
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
607 is_error(double x)
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
608 {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
609 int result = 1; /* presumption of guilt */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
610 assert(errno); /* non-zero errno is a precondition for calling */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
611 if (errno == EDOM)
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
612 PyErr_SetString(PyExc_ValueError, "math domain error");
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
613
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
614 else if (errno == ERANGE) {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
615 /* ANSI C generally requires libm functions to set ERANGE
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
616 * on overflow, but also generally *allows* them to set
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
617 * ERANGE on underflow too. There's no consistency about
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
618 * the latter across platforms.
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
619 * Alas, C99 never requires that errno be set.
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
620 * Here we suppress the underflow errors (libm functions
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
621 * should return a zero on underflow, and +- HUGE_VAL on
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
622 * overflow, so testing the result for zero suffices to
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
623 * distinguish the cases).
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
624 *
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
625 * On some platforms (Ubuntu/ia64) it seems that errno can be
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
626 * set to ERANGE for subnormal results that do *not* underflow
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
627 * to zero. So to be safe, we'll ignore ERANGE whenever the
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
628 * function result is less than one in absolute value.
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
629 */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
630 if (fabs(x) < 1.0)
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
631 result = 0;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
632 else
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
633 PyErr_SetString(PyExc_OverflowError,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
634 "math range error");
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
635 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
636 else
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
637 /* Unexpected math error */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
638 PyErr_SetFromErrno(PyExc_ValueError);
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
639 return result;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
640 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
641
50123
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
642 /*
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
643 math_1 is used to wrap a libm function f that takes a double
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
644 arguments and returns a double.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
645
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
646 The error reporting follows these rules, which are designed to do
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
647 the right thing on C89/C99 platforms and IEEE 754/non IEEE 754
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
648 platforms.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
649
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
650 - a NaN result from non-NaN inputs causes ValueError to be raised
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
651 - an infinite result from finite inputs causes OverflowError to be
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
652 raised if can_overflow is 1, or raises ValueError if can_overflow
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
653 is 0.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
654 - if the result is finite and errno == EDOM then ValueError is
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
655 raised
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
656 - if the result is finite and nonzero and errno == ERANGE then
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
657 OverflowError is raised
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
658
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
659 The last rule is used to catch overflow on platforms which follow
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
660 C89 but for which HUGE_VAL is not an infinity.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
661
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
662 For the majority of one-argument functions these rules are enough
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
663 to ensure that Python's functions behave as specified in 'Annex F'
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
664 of the C99 standard, with the 'invalid' and 'divide-by-zero'
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
665 floating-point exceptions mapping to Python's ValueError and the
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
666 'overflow' floating-point exception mapping to OverflowError.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
667 math_1 only works for functions that don't have singularities *and*
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
668 the possibility of overflow; fortunately, that covers everything we
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
669 care about right now.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
670 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
671
4635
49745ddb4f69 Renamed
Barry Warsaw <barry@python.org>
parents: 4503
diff changeset
672 static PyObject *
44499
31e294d08ce1 Make math.floor and math.ceil return ints instead of floats.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44460
diff changeset
673 math_1_to_whatever(PyObject *arg, double (*func) (double),
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
674 PyObject *(*from_double_func) (double),
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
675 int can_overflow)
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
676 {
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
677 double x, r;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
678 x = PyFloat_AsDouble(arg);
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
679 if (x == -1.0 && PyErr_Occurred())
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
680 return NULL;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
681 errno = 0;
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
682 PyFPE_START_PROTECT("in math_1", return 0);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
683 r = (*func)(x);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
684 PyFPE_END_PROTECT(r);
46616
3f2117d3271f Make floating-point exception error messages slightly more verbose: in
Mark Dickinson <dickinsm@gmail.com>
parents: 46516
diff changeset
685 if (Py_IS_NAN(r) && !Py_IS_NAN(x)) {
3f2117d3271f Make floating-point exception error messages slightly more verbose: in
Mark Dickinson <dickinsm@gmail.com>
parents: 46516
diff changeset
686 PyErr_SetString(PyExc_ValueError,
48331
a6503ae3e19c Quick fix for test_math failures on Solaris 10 buildbot. For future
Mark Dickinson <dickinsm@gmail.com>
parents: 48326
diff changeset
687 "math domain error"); /* invalid arg */
46616
3f2117d3271f Make floating-point exception error messages slightly more verbose: in
Mark Dickinson <dickinsm@gmail.com>
parents: 46516
diff changeset
688 return NULL;
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
689 }
46616
3f2117d3271f Make floating-point exception error messages slightly more verbose: in
Mark Dickinson <dickinsm@gmail.com>
parents: 46516
diff changeset
690 if (Py_IS_INFINITY(r) && Py_IS_FINITE(x)) {
3f2117d3271f Make floating-point exception error messages slightly more verbose: in
Mark Dickinson <dickinsm@gmail.com>
parents: 46516
diff changeset
691 if (can_overflow)
3f2117d3271f Make floating-point exception error messages slightly more verbose: in
Mark Dickinson <dickinsm@gmail.com>
parents: 46516
diff changeset
692 PyErr_SetString(PyExc_OverflowError,
48331
a6503ae3e19c Quick fix for test_math failures on Solaris 10 buildbot. For future
Mark Dickinson <dickinsm@gmail.com>
parents: 48326
diff changeset
693 "math range error"); /* overflow */
46791
8b67685a8bc3 Revert the temporary change in r62624
Mark Dickinson <dickinsm@gmail.com>
parents: 46664
diff changeset
694 else
8b67685a8bc3 Revert the temporary change in r62624
Mark Dickinson <dickinsm@gmail.com>
parents: 46664
diff changeset
695 PyErr_SetString(PyExc_ValueError,
48331
a6503ae3e19c Quick fix for test_math failures on Solaris 10 buildbot. For future
Mark Dickinson <dickinsm@gmail.com>
parents: 48326
diff changeset
696 "math domain error"); /* singularity */
46616
3f2117d3271f Make floating-point exception error messages slightly more verbose: in
Mark Dickinson <dickinsm@gmail.com>
parents: 46516
diff changeset
697 return NULL;
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
698 }
46617
e42fe19ba6fd Whoops. errno should only be tested when the result is finite.
Mark Dickinson <dickinsm@gmail.com>
parents: 46616
diff changeset
699 if (Py_IS_FINITE(r) && errno && is_error(r))
e42fe19ba6fd Whoops. errno should only be tested when the result is finite.
Mark Dickinson <dickinsm@gmail.com>
parents: 46616
diff changeset
700 /* this branch unnecessary on most platforms */
15170
09c7ac188ce2 Stop raising OverflowError on underflows reported by libm (errno==ERANGE and
Tim Peters <tim.peters@gmail.com>
parents: 14616
diff changeset
701 return NULL;
46617
e42fe19ba6fd Whoops. errno should only be tested when the result is finite.
Mark Dickinson <dickinsm@gmail.com>
parents: 46616
diff changeset
702
e42fe19ba6fd Whoops. errno should only be tested when the result is finite.
Mark Dickinson <dickinsm@gmail.com>
parents: 46616
diff changeset
703 return (*from_double_func)(r);
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
704 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
705
56270
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
706 /* variant of math_1, to be used when the function being wrapped is known to
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
707 set errno properly (that is, errno = EDOM for invalid or divide-by-zero,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
708 errno = ERANGE for overflow). */
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
709
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
710 static PyObject *
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
711 math_1a(PyObject *arg, double (*func) (double))
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
712 {
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
713 double x, r;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
714 x = PyFloat_AsDouble(arg);
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
715 if (x == -1.0 && PyErr_Occurred())
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
716 return NULL;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
717 errno = 0;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
718 PyFPE_START_PROTECT("in math_1a", return 0);
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
719 r = (*func)(x);
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
720 PyFPE_END_PROTECT(r);
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
721 if (errno && is_error(r))
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
722 return NULL;
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
723 return PyFloat_FromDouble(r);
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
724 }
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
725
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
726 /*
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
727 math_2 is used to wrap a libm function f that takes two double
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
728 arguments and returns a double.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
729
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
730 The error reporting follows these rules, which are designed to do
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
731 the right thing on C89/C99 platforms and IEEE 754/non IEEE 754
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
732 platforms.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
733
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
734 - a NaN result from non-NaN inputs causes ValueError to be raised
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
735 - an infinite result from finite inputs causes OverflowError to be
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
736 raised.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
737 - if the result is finite and errno == EDOM then ValueError is
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
738 raised
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
739 - if the result is finite and nonzero and errno == ERANGE then
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
740 OverflowError is raised
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
741
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
742 The last rule is used to catch overflow on platforms which follow
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
743 C89 but for which HUGE_VAL is not an infinity.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
744
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
745 For most two-argument functions (copysign, fmod, hypot, atan2)
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
746 these rules are enough to ensure that Python's functions behave as
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
747 specified in 'Annex F' of the C99 standard, with the 'invalid' and
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
748 'divide-by-zero' floating-point exceptions mapping to Python's
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
749 ValueError and the 'overflow' floating-point exception mapping to
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
750 OverflowError.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
751 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
752
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
753 static PyObject *
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
754 math_1(PyObject *arg, double (*func) (double), int can_overflow)
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
755 {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
756 return math_1_to_whatever(arg, func, PyFloat_FromDouble, can_overflow);
44499
31e294d08ce1 Make math.floor and math.ceil return ints instead of floats.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44460
diff changeset
757 }
31e294d08ce1 Make math.floor and math.ceil return ints instead of floats.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44460
diff changeset
758
31e294d08ce1 Make math.floor and math.ceil return ints instead of floats.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44460
diff changeset
759 static PyObject *
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
760 math_1_to_int(PyObject *arg, double (*func) (double), int can_overflow)
44499
31e294d08ce1 Make math.floor and math.ceil return ints instead of floats.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44460
diff changeset
761 {
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
762 return math_1_to_whatever(arg, func, PyLong_FromDouble, can_overflow);
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
763 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
764
4635
49745ddb4f69 Renamed
Barry Warsaw <barry@python.org>
parents: 4503
diff changeset
765 static PyObject *
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
766 math_2(PyObject *args, double (*func) (double, double), char *funcname)
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
767 {
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
768 PyObject *ox, *oy;
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
769 double x, y, r;
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
770 if (! PyArg_UnpackTuple(args, funcname, 2, 2, &ox, &oy))
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
771 return NULL;
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
772 x = PyFloat_AsDouble(ox);
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
773 y = PyFloat_AsDouble(oy);
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
774 if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
775 return NULL;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
776 errno = 0;
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
777 PyFPE_START_PROTECT("in math_2", return 0);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
778 r = (*func)(x, y);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
779 PyFPE_END_PROTECT(r);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
780 if (Py_IS_NAN(r)) {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
781 if (!Py_IS_NAN(x) && !Py_IS_NAN(y))
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
782 errno = EDOM;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
783 else
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
784 errno = 0;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
785 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
786 else if (Py_IS_INFINITY(r)) {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
787 if (Py_IS_FINITE(x) && Py_IS_FINITE(y))
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
788 errno = ERANGE;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
789 else
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
790 errno = 0;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
791 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
792 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
793 return NULL;
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
794 else
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
795 return PyFloat_FromDouble(r);
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
796 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
797
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
798 #define FUNC1(funcname, func, can_overflow, docstring) \
13326
24717405dd89 ANSI-fication, remove Py_PROTO, etc.
Fred Drake <fdrake@acm.org>
parents: 13309
diff changeset
799 static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
800 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
801 }\
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
802 PyDoc_STRVAR(math_##funcname##_doc, docstring);
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
803
56270
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
804 #define FUNC1A(funcname, func, docstring) \
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
805 static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
806 return math_1a(args, func); \
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
807 }\
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
808 PyDoc_STRVAR(math_##funcname##_doc, docstring);
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
809
13326
24717405dd89 ANSI-fication, remove Py_PROTO, etc.
Fred Drake <fdrake@acm.org>
parents: 13309
diff changeset
810 #define FUNC2(funcname, func, docstring) \
24717405dd89 ANSI-fication, remove Py_PROTO, etc.
Fred Drake <fdrake@acm.org>
parents: 13309
diff changeset
811 static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
812 return math_2(args, func, #funcname); \
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
813 }\
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
814 PyDoc_STRVAR(math_##funcname##_doc, docstring);
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
815
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
816 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
817 "acos(x)\n\nReturn the arc cosine (measured in radians) of x.")
57866
9751ddcc1882 Merged revisions 76978 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57808
diff changeset
818 FUNC1(acosh, m_acosh, 0,
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
819 "acosh(x)\n\nReturn the hyperbolic arc cosine (measured in radians) of x.")
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
820 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
821 "asin(x)\n\nReturn the arc sine (measured in radians) of x.")
57866
9751ddcc1882 Merged revisions 76978 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57808
diff changeset
822 FUNC1(asinh, m_asinh, 0,
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
823 "asinh(x)\n\nReturn the hyperbolic arc sine (measured in radians) of x.")
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
824 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
825 "atan(x)\n\nReturn the arc tangent (measured in radians) of x.")
46516
ec48490b969a Merged revisions 62420-62421,62423-62424 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46505
diff changeset
826 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
827 "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
828 "Unlike atan(y/x), the signs of both x and y are considered.")
57866
9751ddcc1882 Merged revisions 76978 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57808
diff changeset
829 FUNC1(atanh, m_atanh, 0,
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
830 "atanh(x)\n\nReturn the hyperbolic arc tangent (measured in radians) of x.")
42754
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
831
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
832 static PyObject * math_ceil(PyObject *self, PyObject *number) {
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
833 static PyObject *ceil_str = NULL;
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
834 PyObject *method;
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
835
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
836 if (ceil_str == NULL) {
45029
ef2d3bf8383d Merged revisions 60379-60382 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44999
diff changeset
837 ceil_str = PyUnicode_InternFromString("__ceil__");
42754
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
838 if (ceil_str == NULL)
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
839 return NULL;
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
840 }
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
841
44351
86a2679dca46 #1629: Renamed Py_Size, Py_Type and Py_Refcnt to Py_SIZE, Py_TYPE and Py_REFCNT.
Christian Heimes <christian@cheimes.de>
parents: 42754
diff changeset
842 method = _PyType_Lookup(Py_TYPE(number), ceil_str);
42754
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
843 if (method == NULL)
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
844 return math_1_to_int(number, ceil, 0);
42754
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
845 else
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
846 return PyObject_CallFunction(method, "O", number);
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
847 }
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
848
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
849 PyDoc_STRVAR(math_ceil_doc,
44499
31e294d08ce1 Make math.floor and math.ceil return ints instead of floats.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44460
diff changeset
850 "ceil(x)\n\nReturn the ceiling of x as an int.\n"
42754
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
851 "This is the smallest integral value >= x.");
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
852
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
853 FUNC2(copysign, copysign,
57209
b354c1b6b476 Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 56270
diff changeset
854 "copysign(x, y)\n\nReturn x with the sign of y.")
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
855 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
856 "cos(x)\n\nReturn the cosine of x (measured in radians).")
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
857 FUNC1(cosh, cosh, 1,
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
858 "cosh(x)\n\nReturn the hyperbolic cosine of x.")
57770
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
859 FUNC1A(erf, m_erf,
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
860 "erf(x)\n\nError function at x.")
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
861 FUNC1A(erfc, m_erfc,
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
862 "erfc(x)\n\nComplementary error function at x.")
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
863 FUNC1(exp, exp, 1,
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
864 "exp(x)\n\nReturn e raised to the power of x.")
57758
b45ca11b9a3e Merged revisions 76861 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57660
diff changeset
865 FUNC1(expm1, m_expm1, 1,
b45ca11b9a3e Merged revisions 76861 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57660
diff changeset
866 "expm1(x)\n\nReturn exp(x)-1.\n"
b45ca11b9a3e Merged revisions 76861 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57660
diff changeset
867 "This function avoids the loss of precision involved in the direct "
b45ca11b9a3e Merged revisions 76861 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57660
diff changeset
868 "evaluation of exp(x)-1 for small x.")
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
869 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
870 "fabs(x)\n\nReturn the absolute value of the float x.")
42754
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
871
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
872 static PyObject * math_floor(PyObject *self, PyObject *number) {
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
873 static PyObject *floor_str = NULL;
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
874 PyObject *method;
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
875
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
876 if (floor_str == NULL) {
45029
ef2d3bf8383d Merged revisions 60379-60382 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44999
diff changeset
877 floor_str = PyUnicode_InternFromString("__floor__");
42754
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
878 if (floor_str == NULL)
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
879 return NULL;
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
880 }
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
881
44351
86a2679dca46 #1629: Renamed Py_Size, Py_Type and Py_Refcnt to Py_SIZE, Py_TYPE and Py_REFCNT.
Christian Heimes <christian@cheimes.de>
parents: 42754
diff changeset
882 method = _PyType_Lookup(Py_TYPE(number), floor_str);
42754
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
883 if (method == NULL)
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
884 return math_1_to_int(number, floor, 0);
42754
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
885 else
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
886 return PyObject_CallFunction(method, "O", number);
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
887 }
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
888
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
889 PyDoc_STRVAR(math_floor_doc,
44499
31e294d08ce1 Make math.floor and math.ceil return ints instead of floats.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44460
diff changeset
890 "floor(x)\n\nReturn the floor of x as an int.\n"
42754
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
891 "This is the largest integral value <= x.");
1c98b445d847 Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
Guido van Rossum <guido@python.org>
parents: 42334
diff changeset
892
56270
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
893 FUNC1A(gamma, m_tgamma,
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
894 "gamma(x)\n\nGamma function at x.")
57660
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
895 FUNC1A(lgamma, m_lgamma,
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
896 "lgamma(x)\n\nNatural logarithm of absolute value of Gamma function at x.")
57866
9751ddcc1882 Merged revisions 76978 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57808
diff changeset
897 FUNC1(log1p, m_log1p, 1,
57209
b354c1b6b476 Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 56270
diff changeset
898 "log1p(x)\n\nReturn the natural logarithm of 1+x (base e).\n"
b354c1b6b476 Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 56270
diff changeset
899 "The result is computed in a way which is accurate for x near zero.")
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
900 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
901 "sin(x)\n\nReturn the sine of x (measured in radians).")
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
902 FUNC1(sinh, sinh, 1,
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
903 "sinh(x)\n\nReturn the hyperbolic sine of x.")
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
904 FUNC1(sqrt, sqrt, 0,
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
905 "sqrt(x)\n\nReturn the square root of x.")
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
906 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
907 "tan(x)\n\nReturn the tangent of x (measured in radians).")
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
908 FUNC1(tanh, tanh, 0,
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
909 "tanh(x)\n\nReturn the hyperbolic tangent of x.")
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
910
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
911 /* Precision summation function as msum() by Raymond Hettinger in
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
912 <http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/393090>,
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
913 enhanced with the exact partials sum and roundoff from Mark
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
914 Dickinson's post at <http://bugs.python.org/file10357/msum4.py>.
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
915 See those links for more details, proofs and other references.
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
916
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
917 Note 1: IEEE 754R floating point semantics are assumed,
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
918 but the current implementation does not re-establish special
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
919 value semantics across iterations (i.e. handling -Inf + Inf).
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
920
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
921 Note 2: No provision is made for intermediate overflow handling;
47559
2925b568aacc Merged revisions 63562,63570,63728,63734,63784,63788,63802,63817,63827,63839,63887,63975,63998 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47320
diff changeset
922 therefore, sum([1e+308, 1e-308, 1e+308]) returns 1e+308 while
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
923 sum([1e+308, 1e+308, 1e-308]) raises an OverflowError due to the
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
924 overflow of the first partial sum.
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
925
48407
e22deaeb6c1b Merged revisions 64365,64370,64406,64408-64409,64412,64416-64417,64420-64421,64425-64428 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 48331
diff changeset
926 Note 3: The intermediate values lo, yr, and hi are declared volatile so
e22deaeb6c1b Merged revisions 64365,64370,64406,64408-64409,64412,64416-64417,64420-64421,64425-64428 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 48331
diff changeset
927 aggressive compilers won't algebraically reduce lo to always be exactly 0.0.
47559
2925b568aacc Merged revisions 63562,63570,63728,63734,63784,63788,63802,63817,63827,63839,63887,63975,63998 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47320
diff changeset
928 Also, the volatile declaration forces the values to be stored in memory as
2925b568aacc Merged revisions 63562,63570,63728,63734,63784,63788,63802,63817,63827,63839,63887,63975,63998 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47320
diff changeset
929 regular doubles instead of extended long precision (80-bit) values. This
48407
e22deaeb6c1b Merged revisions 64365,64370,64406,64408-64409,64412,64416-64417,64420-64421,64425-64428 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 48331
diff changeset
930 prevents double rounding because any addition or subtraction of two doubles
47559
2925b568aacc Merged revisions 63562,63570,63728,63734,63784,63788,63802,63817,63827,63839,63887,63975,63998 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47320
diff changeset
931 can be resolved exactly into double-sized hi and lo values. As long as the
2925b568aacc Merged revisions 63562,63570,63728,63734,63784,63788,63802,63817,63827,63839,63887,63975,63998 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47320
diff changeset
932 hi value gets forced into a double before yr and lo are computed, the extra
2925b568aacc Merged revisions 63562,63570,63728,63734,63784,63788,63802,63817,63827,63839,63887,63975,63998 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47320
diff changeset
933 bits in downstream extended precision operations (x87 for example) will be
2925b568aacc Merged revisions 63562,63570,63728,63734,63784,63788,63802,63817,63827,63839,63887,63975,63998 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47320
diff changeset
934 exactly zero and therefore can be losslessly stored back into a double,
2925b568aacc Merged revisions 63562,63570,63728,63734,63784,63788,63802,63817,63827,63839,63887,63975,63998 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47320
diff changeset
935 thereby preventing double rounding.
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
936
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
937 Note 4: A similar implementation is in Modules/cmathmodule.c.
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
938 Be sure to update both when making changes.
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
939
48606
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
940 Note 5: The signature of math.fsum() differs from __builtin__.sum()
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
941 because the start argument doesn't make sense in the context of
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
942 accurate summation. Since the partials table is collapsed before
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
943 returning a result, sum(seq2, start=sum(seq1)) may not equal the
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
944 accurate result returned by sum(itertools.chain(seq1, seq2)).
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
945 */
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
946
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
947 #define NUM_PARTIALS 32 /* initial partials array size, on stack */
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
948
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
949 /* Extend the partials array p[] by doubling its size. */
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
950 static int /* non-zero on error */
48606
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
951 _fsum_realloc(double **p_ptr, Py_ssize_t n,
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
952 double *ps, Py_ssize_t *m_ptr)
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
953 {
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
954 void *v = NULL;
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
955 Py_ssize_t m = *m_ptr;
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
956
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
957 m += m; /* double */
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
958 if (n < m && m < (PY_SSIZE_T_MAX / sizeof(double))) {
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
959 double *p = *p_ptr;
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
960 if (p == ps) {
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
961 v = PyMem_Malloc(sizeof(double) * m);
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
962 if (v != NULL)
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
963 memcpy(v, ps, sizeof(double) * n);
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
964 }
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
965 else
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
966 v = PyMem_Realloc(p, sizeof(double) * m);
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
967 }
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
968 if (v == NULL) { /* size overflow or no memory */
48606
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
969 PyErr_SetString(PyExc_MemoryError, "math.fsum partials");
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
970 return 1;
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
971 }
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
972 *p_ptr = (double*) v;
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
973 *m_ptr = m;
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
974 return 0;
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
975 }
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
976
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
977 /* Full precision summation of a sequence of floats.
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
978
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
979 def msum(iterable):
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
980 partials = [] # sorted, non-overlapping partial sums
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
981 for x in iterable:
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
982 i = 0
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
983 for y in partials:
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
984 if abs(x) < abs(y):
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
985 x, y = y, x
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
986 hi = x + y
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
987 lo = y - (hi - x)
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
988 if lo:
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
989 partials[i] = lo
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
990 i += 1
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
991 x = hi
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
992 partials[i:] = [x]
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
993 return sum_exact(partials)
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
994
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
995 Rounded x+y stored in hi with the roundoff stored in lo. Together hi+lo
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
996 are exactly equal to x+y. The inner loop applies hi/lo summation to each
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
997 partial so that the list of partial sums remains exact.
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
998
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
999 Sum_exact() adds the partial sums exactly and correctly rounds the final
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1000 result (using the round-half-to-even rule). The items in partials remain
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1001 non-zero, non-special, non-overlapping and strictly increasing in
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1002 magnitude, but possibly not all having the same sign.
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1003
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1004 Depends on IEEE 754 arithmetic guarantees and half-even rounding.
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1005 */
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1006
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1007 static PyObject*
48606
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1008 math_fsum(PyObject *self, PyObject *seq)
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1009 {
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1010 PyObject *item, *iter, *sum = NULL;
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1011 Py_ssize_t i, j, n = 0, m = NUM_PARTIALS;
47559
2925b568aacc Merged revisions 63562,63570,63728,63734,63784,63788,63802,63817,63827,63839,63887,63975,63998 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47320
diff changeset
1012 double x, y, t, ps[NUM_PARTIALS], *p = ps;
48606
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1013 double xsave, special_sum = 0.0, inf_sum = 0.0;
47559
2925b568aacc Merged revisions 63562,63570,63728,63734,63784,63788,63802,63817,63827,63839,63887,63975,63998 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47320
diff changeset
1014 volatile double hi, yr, lo;
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1015
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1016 iter = PyObject_GetIter(seq);
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1017 if (iter == NULL)
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1018 return NULL;
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1019
48606
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1020 PyFPE_START_PROTECT("fsum", Py_DECREF(iter); return NULL)
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1021
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1022 for(;;) { /* for x in iterable */
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1023 assert(0 <= n && n <= m);
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1024 assert((m == NUM_PARTIALS && p == ps) ||
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1025 (m > NUM_PARTIALS && p != NULL));
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1026
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1027 item = PyIter_Next(iter);
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1028 if (item == NULL) {
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1029 if (PyErr_Occurred())
48606
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1030 goto _fsum_error;
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1031 break;
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1032 }
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1033 x = PyFloat_AsDouble(item);
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1034 Py_DECREF(item);
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1035 if (PyErr_Occurred())
48606
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1036 goto _fsum_error;
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1037
48606
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1038 xsave = x;
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1039 for (i = j = 0; j < n; j++) { /* for y in partials */
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1040 y = p[j];
47559
2925b568aacc Merged revisions 63562,63570,63728,63734,63784,63788,63802,63817,63827,63839,63887,63975,63998 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47320
diff changeset
1041 if (fabs(x) < fabs(y)) {
48606
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1042 t = x; x = y; y = t;
47559
2925b568aacc Merged revisions 63562,63570,63728,63734,63784,63788,63802,63817,63827,63839,63887,63975,63998 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47320
diff changeset
1043 }
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1044 hi = x + y;
47559
2925b568aacc Merged revisions 63562,63570,63728,63734,63784,63788,63802,63817,63827,63839,63887,63975,63998 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47320
diff changeset
1045 yr = hi - x;
2925b568aacc Merged revisions 63562,63570,63728,63734,63784,63788,63802,63817,63827,63839,63887,63975,63998 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47320
diff changeset
1046 lo = y - yr;
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1047 if (lo != 0.0)
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1048 p[i++] = lo;
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1049 x = hi;
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1050 }
48606
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1051
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1052 n = i; /* ps[i:] = [x] */
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1053 if (x != 0.0) {
48606
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1054 if (! Py_IS_FINITE(x)) {
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1055 /* a nonfinite x could arise either as
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1056 a result of intermediate overflow, or
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1057 as a result of a nan or inf in the
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1058 summands */
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1059 if (Py_IS_FINITE(xsave)) {
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1060 PyErr_SetString(PyExc_OverflowError,
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1061 "intermediate overflow in fsum");
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1062 goto _fsum_error;
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1063 }
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1064 if (Py_IS_INFINITY(xsave))
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1065 inf_sum += xsave;
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1066 special_sum += xsave;
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1067 /* reset partials */
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1068 n = 0;
48606
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1069 }
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1070 else if (n >= m && _fsum_realloc(&p, n, ps, &m))
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1071 goto _fsum_error;
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1072 else
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1073 p[n++] = x;
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1074 }
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1075 }
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1076
48606
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1077 if (special_sum != 0.0) {
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1078 if (Py_IS_NAN(inf_sum))
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1079 PyErr_SetString(PyExc_ValueError,
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1080 "-inf + inf in fsum");
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1081 else
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1082 sum = PyFloat_FromDouble(special_sum);
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1083 goto _fsum_error;
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1084 }
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1085
47559
2925b568aacc Merged revisions 63562,63570,63728,63734,63784,63788,63802,63817,63827,63839,63887,63975,63998 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47320
diff changeset
1086 hi = 0.0;
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1087 if (n > 0) {
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1088 hi = p[--n];
48606
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1089 /* sum_exact(ps, hi) from the top, stop when the sum becomes
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1090 inexact. */
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1091 while (n > 0) {
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1092 x = hi;
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1093 y = p[--n];
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1094 assert(fabs(y) < fabs(x));
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1095 hi = x + y;
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1096 yr = hi - x;
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1097 lo = y - yr;
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1098 if (lo != 0.0)
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1099 break;
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1100 }
48606
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1101 /* Make half-even rounding work across multiple partials.
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1102 Needed so that sum([1e-16, 1, 1e16]) will round-up the last
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1103 digit to two instead of down to zero (the 1e-16 makes the 1
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1104 slightly closer to two). With a potential 1 ULP rounding
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1105 error fixed-up, math.fsum() can guarantee commutativity. */
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1106 if (n > 0 && ((lo < 0.0 && p[n-1] < 0.0) ||
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1107 (lo > 0.0 && p[n-1] > 0.0))) {
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1108 y = lo * 2.0;
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1109 x = hi + y;
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1110 yr = x - hi;
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1111 if (y == yr)
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1112 hi = x;
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1113 }
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1114 }
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1115 sum = PyFloat_FromDouble(hi);
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1116
48606
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1117 _fsum_error:
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1118 PyFPE_END_PROTECT(hi)
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1119 Py_DECREF(iter);
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1120 if (p != ps)
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1121 PyMem_Free(p);
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1122 return sum;
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1123 }
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1124
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1125 #undef NUM_PARTIALS
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1126
48606
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1127 PyDoc_STRVAR(math_fsum_doc,
57209
b354c1b6b476 Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 56270
diff changeset
1128 "fsum(iterable)\n\n\
47320
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1129 Return an accurate floating point sum of values in the iterable.\n\
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1130 Assumes IEEE-754 floating point arithmetic.");
3975ec2b0de2 Merged revisions 63542-63544,63546,63553,63563-63564,63567,63569,63576 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47175
diff changeset
1131
4635
49745ddb4f69 Renamed
Barry Warsaw <barry@python.org>
parents: 4503
diff changeset
1132 static PyObject *
47562
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1133 math_factorial(PyObject *self, PyObject *arg)
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1134 {
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1135 long i, x;
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1136 PyObject *result, *iobj, *newresult;
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1137
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1138 if (PyFloat_Check(arg)) {
57808
53f21f08af0d Merged revisions 76916 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57770
diff changeset
1139 PyObject *lx;
47562
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1140 double dx = PyFloat_AS_DOUBLE((PyFloatObject *)arg);
57808
53f21f08af0d Merged revisions 76916 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57770
diff changeset
1141 if (!(Py_IS_FINITE(dx) && dx == floor(dx))) {
47562
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1142 PyErr_SetString(PyExc_ValueError,
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1143 "factorial() only accepts integral values");
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1144 return NULL;
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1145 }
57808
53f21f08af0d Merged revisions 76916 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57770
diff changeset
1146 lx = PyLong_FromDouble(dx);
53f21f08af0d Merged revisions 76916 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57770
diff changeset
1147 if (lx == NULL)
53f21f08af0d Merged revisions 76916 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57770
diff changeset
1148 return NULL;
53f21f08af0d Merged revisions 76916 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57770
diff changeset
1149 x = PyLong_AsLong(lx);
53f21f08af0d Merged revisions 76916 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57770
diff changeset
1150 Py_DECREF(lx);
47562
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1151 }
57808
53f21f08af0d Merged revisions 76916 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57770
diff changeset
1152 else
53f21f08af0d Merged revisions 76916 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57770
diff changeset
1153 x = PyLong_AsLong(arg);
47562
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1154
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1155 if (x == -1 && PyErr_Occurred())
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1156 return NULL;
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1157 if (x < 0) {
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1158 PyErr_SetString(PyExc_ValueError,
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1159 "factorial() not defined for negative values");
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1160 return NULL;
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1161 }
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1162
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1163 result = (PyObject *)PyLong_FromLong(1);
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1164 if (result == NULL)
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1165 return NULL;
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1166 for (i=1 ; i<=x ; i++) {
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1167 iobj = (PyObject *)PyLong_FromLong(i);
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1168 if (iobj == NULL)
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1169 goto error;
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1170 newresult = PyNumber_Multiply(result, iobj);
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1171 Py_DECREF(iobj);
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1172 if (newresult == NULL)
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1173 goto error;
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1174 Py_DECREF(result);
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1175 result = newresult;
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1176 }
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1177 return result;
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1178
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1179 error:
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1180 Py_DECREF(result);
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1181 return NULL;
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1182 }
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1183
50250
1adfabcbe073 Merged revisions 67886-67887 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50123
diff changeset
1184 PyDoc_STRVAR(math_factorial_doc,
1adfabcbe073 Merged revisions 67886-67887 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50123
diff changeset
1185 "factorial(x) -> Integral\n"
1adfabcbe073 Merged revisions 67886-67887 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50123
diff changeset
1186 "\n"
1adfabcbe073 Merged revisions 67886-67887 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50123
diff changeset
1187 "Find x!. Raise a ValueError if x is negative or non-integral.");
47562
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1188
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1189 static PyObject *
45082
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1190 math_trunc(PyObject *self, PyObject *number)
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1191 {
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1192 static PyObject *trunc_str = NULL;
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1193 PyObject *trunc;
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1194
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1195 if (Py_TYPE(number)->tp_dict == NULL) {
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1196 if (PyType_Ready(Py_TYPE(number)) < 0)
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1197 return NULL;
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1198 }
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1199
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1200 if (trunc_str == NULL) {
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1201 trunc_str = PyUnicode_InternFromString("__trunc__");
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1202 if (trunc_str == NULL)
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1203 return NULL;
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1204 }
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1205
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1206 trunc = _PyType_Lookup(Py_TYPE(number), trunc_str);
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1207 if (trunc == NULL) {
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1208 PyErr_Format(PyExc_TypeError,
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1209 "type %.100s doesn't define __trunc__ method",
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1210 Py_TYPE(number)->tp_name);
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1211 return NULL;
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1212 }
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1213 return PyObject_CallFunctionObjArgs(trunc, number, NULL);
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1214 }
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1215
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1216 PyDoc_STRVAR(math_trunc_doc,
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1217 "trunc(x:Real) -> Integral\n"
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1218 "\n"
45134
bdcf40d1b38e Merged revisions 60481,60485,60489-60520,60523-60527,60530-60533,60535-60538,60540-60551 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45082
diff changeset
1219 "Truncates x to the nearest Integral toward 0. Uses the __trunc__ magic method.");
45082
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1220
d7540031b959 Merged revisions 60475-60479,60481-60488 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45029
diff changeset
1221 static PyObject *
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1222 math_frexp(PyObject *self, PyObject *arg)
407
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1223 {
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1224 int i;
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1225 double x = PyFloat_AsDouble(arg);
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1226 if (x == -1.0 && PyErr_Occurred())
407
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1227 return NULL;
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1228 /* deal with special cases directly, to sidestep platform
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1229 differences */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1230 if (Py_IS_NAN(x) || Py_IS_INFINITY(x) || !x) {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1231 i = 0;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1232 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1233 else {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1234 PyFPE_START_PROTECT("in math_frexp", return 0);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1235 x = frexp(x, &i);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1236 PyFPE_END_PROTECT(x);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1237 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1238 return Py_BuildValue("(di)", x, i);
407
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1239 }
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1240
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
1241 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
1242 "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
1243 "\n"
b4521436e8f8 Mechanical fiddling to make this easier to work with in my editor.
Tim Peters <tim.peters@gmail.com>
parents: 19048
diff changeset
1244 "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
1245 "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
1246 "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
1247
4635
49745ddb4f69 Renamed
Barry Warsaw <barry@python.org>
parents: 4503
diff changeset
1248 static PyObject *
13326
24717405dd89 ANSI-fication, remove Py_PROTO, etc.
Fred Drake <fdrake@acm.org>
parents: 13309
diff changeset
1249 math_ldexp(PyObject *self, PyObject *args)
407
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1250 {
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1251 double x, r;
47063
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1252 PyObject *oexp;
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1253 long exp;
58125
9b9adc42c73a Merged revisions 77275 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58088
diff changeset
1254 int overflow;
47063
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1255 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
1256 return NULL;
47063
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1257
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1258 if (PyLong_Check(oexp)) {
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1259 /* on overflow, replace exponent with either LONG_MAX
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1260 or LONG_MIN, depending on the sign. */
58125
9b9adc42c73a Merged revisions 77275 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58088
diff changeset
1261 exp = PyLong_AsLongAndOverflow(oexp, &overflow);
9b9adc42c73a Merged revisions 77275 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58088
diff changeset
1262 if (exp == -1 && PyErr_Occurred())
9b9adc42c73a Merged revisions 77275 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58088
diff changeset
1263 return NULL;
9b9adc42c73a Merged revisions 77275 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58088
diff changeset
1264 if (overflow)
9b9adc42c73a Merged revisions 77275 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58088
diff changeset
1265 exp = overflow < 0 ? LONG_MIN : LONG_MAX;
47063
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1266 }
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1267 else {
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1268 PyErr_SetString(PyExc_TypeError,
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1269 "Expected an int or long as second argument "
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1270 "to ldexp.");
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1271 return NULL;
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1272 }
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1273
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1274 if (x == 0. || !Py_IS_FINITE(x)) {
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1275 /* NaNs, zeros and infinities are returned unchanged */
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1276 r = x;
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1277 errno = 0;
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1278 } else if (exp > INT_MAX) {
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1279 /* overflow */
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1280 r = copysign(Py_HUGE_VAL, x);
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1281 errno = ERANGE;
47063
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1282 } else if (exp < INT_MIN) {
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1283 /* underflow to +-0 */
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1284 r = copysign(0., x);
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1285 errno = 0;
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1286 } else {
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1287 errno = 0;
47063
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1288 PyFPE_START_PROTECT("in math_ldexp", return 0);
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1289 r = ldexp(x, (int)exp);
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1290 PyFPE_END_PROTECT(r);
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1291 if (Py_IS_INFINITY(r))
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1292 errno = ERANGE;
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1293 }
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1294
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1295 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
1296 return NULL;
47063
081c15806e28 Merged revisions 62914-62916,62918-62919,62921-62922,62924-62942,62944-62945,62947-62949 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 46791
diff changeset
1297 return PyFloat_FromDouble(r);
407
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1298 }
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1299
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
1300 PyDoc_STRVAR(math_ldexp_doc,
57209
b354c1b6b476 Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 56270
diff changeset
1301 "ldexp(x, i)\n\n\
b354c1b6b476 Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 56270
diff changeset
1302 Return x * (2**i).");
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
1303
4635
49745ddb4f69 Renamed
Barry Warsaw <barry@python.org>
parents: 4503
diff changeset
1304 static PyObject *
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1305 math_modf(PyObject *self, PyObject *arg)
407
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1306 {
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1307 double y, x = PyFloat_AsDouble(arg);
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1308 if (x == -1.0 && PyErr_Occurred())
407
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1309 return NULL;
46505
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1310 /* some platforms don't do the right thing for NaNs and
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1311 infinities, so we take care of special cases directly. */
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1312 if (!Py_IS_FINITE(x)) {
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1313 if (Py_IS_INFINITY(x))
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1314 return Py_BuildValue("(dd)", copysign(0., x), x);
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1315 else if (Py_IS_NAN(x))
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1316 return Py_BuildValue("(dd)", x, x);
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1317 }
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1318
407
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1319 errno = 0;
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1320 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
1321 x = modf(x, &y);
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1322 PyFPE_END_PROTECT(x);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1323 return Py_BuildValue("(dd)", x, y);
407
9b3d557665a9 Added frexp, ldexp, modf, fmod.
Guido van Rossum <guido@python.org>
parents: 320
diff changeset
1324 }
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1325
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
1326 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
1327 "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
1328 "\n"
b4521436e8f8 Mechanical fiddling to make this easier to work with in my editor.
Tim Peters <tim.peters@gmail.com>
parents: 19048
diff changeset
1329 "Return the fractional and integer parts of x. Both results carry the sign\n"
50250
1adfabcbe073 Merged revisions 67886-67887 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50123
diff changeset
1330 "of x and are floats.");
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
1331
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
1332 /* 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
1333 do that by itself -- loghelper can. func is log or log10, and name is
58088
46d60e5ff103 Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57866
diff changeset
1334 "log" or "log10". Note that overflow of the result isn't possible: a long
46d60e5ff103 Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57866
diff changeset
1335 can contain no more than INT_MAX * SHIFT bits, so has value certainly less
46d60e5ff103 Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57866
diff changeset
1336 than 2**(2**64 * 2**16) == 2**2**80, and log2 of that is 2**80, which is
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
1337 small enough to fit in an IEEE single. log and log10 are even smaller.
58088
46d60e5ff103 Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57866
diff changeset
1338 However, intermediate overflow is possible for a long if the number of bits
46d60e5ff103 Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57866
diff changeset
1339 in that long is larger than PY_SSIZE_T_MAX. */
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
1340
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1341 static PyObject*
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1342 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
1343 {
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1344 /* 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
1345 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
1346 double x;
58088
46d60e5ff103 Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57866
diff changeset
1347 Py_ssize_t e;
46d60e5ff103 Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57866
diff changeset
1348 x = _PyLong_Frexp((PyLongObject *)arg, &e);
46d60e5ff103 Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57866
diff changeset
1349 if (x == -1.0 && PyErr_Occurred())
46d60e5ff103 Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57866
diff changeset
1350 return NULL;
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
1351 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
1352 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
1353 "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
1354 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
1355 }
58088
46d60e5ff103 Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57866
diff changeset
1356 /* Special case for log(1), to make sure we get an
46d60e5ff103 Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57866
diff changeset
1357 exact result there. */
46d60e5ff103 Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57866
diff changeset
1358 if (e == 1 && x == 0.5)
46d60e5ff103 Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57866
diff changeset
1359 return PyFloat_FromDouble(0.0);
46d60e5ff103 Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57866
diff changeset
1360 /* Value is ~= x * 2**e, so the log ~= log(x) + log(2) * e. */
46d60e5ff103 Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57866
diff changeset
1361 x = func(x) + func(2.0) * e;
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
1362 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
1363 }
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1364
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1365 /* Else let libm handle it by itself. */
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1366 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
1367 }
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1368
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1369 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
1370 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
1371 {
26661
b12e326b4ea2 Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
Raymond Hettinger <python@rcn.com>
parents: 24471
diff changeset
1372 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
1373 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
1374 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
1375 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
1376
26818
e094a03a80ff SF patch #659536: Use PyArg_UnpackTuple where possible.
Raymond Hettinger <python@rcn.com>
parents: 26661
diff changeset
1377 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
1378 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
1379
50123
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
1380 num = loghelper(arg, m_log, "log");
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1381 if (num == NULL || base == NULL)
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1382 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
1383
50123
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
1384 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
1385 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
1386 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
1387 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
1388 }
b12e326b4ea2 Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
Raymond Hettinger <python@rcn.com>
parents: 24471
diff changeset
1389
37191
4bfe8afe8f65 Get rid of remnants of integer division
Neal Norwitz <nnorwitz@gmail.com>
parents: 36324
diff changeset
1390 ans = PyNumber_TrueDivide(num, den);
26661
b12e326b4ea2 Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
Raymond Hettinger <python@rcn.com>
parents: 24471
diff changeset
1391 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
1392 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
1393 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
1394 }
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1395
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
1396 PyDoc_STRVAR(math_log_doc,
57209
b354c1b6b476 Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 56270
diff changeset
1397 "log(x[, base])\n\n\
b354c1b6b476 Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 56270
diff changeset
1398 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
1399 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
1400
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1401 static PyObject *
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1402 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
1403 {
50123
20a84e063052 Merged revisions 67708 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48606
diff changeset
1404 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
1405 }
9433dd3c197e Return reasonable results for math.log(long) and math.log10(long) (we were
Tim Peters <tim.peters@gmail.com>
parents: 19712
diff changeset
1406
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
1407 PyDoc_STRVAR(math_log10_doc,
57209
b354c1b6b476 Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 56270
diff changeset
1408 "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
1409
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1410 static PyObject *
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1411 math_fmod(PyObject *self, PyObject *args)
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1412 {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1413 PyObject *ox, *oy;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1414 double r, x, y;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1415 if (! PyArg_UnpackTuple(args, "fmod", 2, 2, &ox, &oy))
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1416 return NULL;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1417 x = PyFloat_AsDouble(ox);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1418 y = PyFloat_AsDouble(oy);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1419 if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1420 return NULL;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1421 /* fmod(x, +/-Inf) returns x for finite x. */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1422 if (Py_IS_INFINITY(y) && Py_IS_FINITE(x))
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1423 return PyFloat_FromDouble(x);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1424 errno = 0;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1425 PyFPE_START_PROTECT("in math_fmod", return 0);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1426 r = fmod(x, y);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1427 PyFPE_END_PROTECT(r);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1428 if (Py_IS_NAN(r)) {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1429 if (!Py_IS_NAN(x) && !Py_IS_NAN(y))
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1430 errno = EDOM;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1431 else
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1432 errno = 0;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1433 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1434 if (errno && is_error(r))
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1435 return NULL;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1436 else
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1437 return PyFloat_FromDouble(r);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1438 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1439
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1440 PyDoc_STRVAR(math_fmod_doc,
57209
b354c1b6b476 Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 56270
diff changeset
1441 "fmod(x, y)\n\nReturn fmod(x, y), according to platform C."
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1442 " x % y may differ.");
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1443
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1444 static PyObject *
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1445 math_hypot(PyObject *self, PyObject *args)
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1446 {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1447 PyObject *ox, *oy;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1448 double r, x, y;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1449 if (! PyArg_UnpackTuple(args, "hypot", 2, 2, &ox, &oy))
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1450 return NULL;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1451 x = PyFloat_AsDouble(ox);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1452 y = PyFloat_AsDouble(oy);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1453 if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1454 return NULL;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1455 /* hypot(x, +/-Inf) returns Inf, even if x is a NaN. */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1456 if (Py_IS_INFINITY(x))
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1457 return PyFloat_FromDouble(fabs(x));
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1458 if (Py_IS_INFINITY(y))
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1459 return PyFloat_FromDouble(fabs(y));
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1460 errno = 0;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1461 PyFPE_START_PROTECT("in math_hypot", return 0);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1462 r = hypot(x, y);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1463 PyFPE_END_PROTECT(r);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1464 if (Py_IS_NAN(r)) {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1465 if (!Py_IS_NAN(x) && !Py_IS_NAN(y))
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1466 errno = EDOM;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1467 else
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1468 errno = 0;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1469 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1470 else if (Py_IS_INFINITY(r)) {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1471 if (Py_IS_FINITE(x) && Py_IS_FINITE(y))
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1472 errno = ERANGE;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1473 else
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1474 errno = 0;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1475 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1476 if (errno && is_error(r))
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1477 return NULL;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1478 else
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1479 return PyFloat_FromDouble(r);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1480 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1481
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1482 PyDoc_STRVAR(math_hypot_doc,
57209
b354c1b6b476 Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 56270
diff changeset
1483 "hypot(x, y)\n\nReturn the Euclidean distance, sqrt(x*x + y*y).");
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1484
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1485 /* pow can't use math_2, but needs its own wrapper: the problem is
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1486 that an infinite result can arise either as a result of overflow
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1487 (in which case OverflowError should be raised) or as a result of
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1488 e.g. 0.**-5. (for which ValueError needs to be raised.)
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1489 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1490
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1491 static PyObject *
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1492 math_pow(PyObject *self, PyObject *args)
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1493 {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1494 PyObject *ox, *oy;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1495 double r, x, y;
46505
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1496 int odd_y;
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1497
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1498 if (! PyArg_UnpackTuple(args, "pow", 2, 2, &ox, &oy))
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1499 return NULL;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1500 x = PyFloat_AsDouble(ox);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1501 y = PyFloat_AsDouble(oy);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1502 if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1503 return NULL;
46505
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1504
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1505 /* deal directly with IEEE specials, to cope with problems on various
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1506 platforms whose semantics don't exactly match C99 */
46664
031dfe455585 Merged revisions 62425-62429,62434-62436,62441,62444,62446-62448,62450-62455,62463,62465-62466,62469,62474,62476-62478,62480,62485,62492,62497-62498,62500,62507,62513-62514,62516,62521,62531,62535,62545-62546,62548-62551,62553-62559,62569,62574,62577,62593,62595,62604-62606,62608,62616,62626-62627,62636,62638,62644-62645,62647-62648,62651-62653,62656,62661,62663,62680,62686-62687,62696,62699-62703,62711 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46621
diff changeset
1507 r = 0.; /* silence compiler warning */
46505
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1508 if (!Py_IS_FINITE(x) || !Py_IS_FINITE(y)) {
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1509 errno = 0;
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1510 if (Py_IS_NAN(x))
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1511 r = y == 0. ? 1. : x; /* NaN**0 = 1 */
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1512 else if (Py_IS_NAN(y))
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1513 r = x == 1. ? 1. : y; /* 1**NaN = 1 */
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1514 else if (Py_IS_INFINITY(x)) {
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1515 odd_y = Py_IS_FINITE(y) && fmod(fabs(y), 2.0) == 1.0;
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1516 if (y > 0.)
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1517 r = odd_y ? x : fabs(x);
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1518 else if (y == 0.)
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1519 r = 1.;
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1520 else /* y < 0. */
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1521 r = odd_y ? copysign(0., x) : 0.;
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1522 }
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1523 else if (Py_IS_INFINITY(y)) {
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1524 if (fabs(x) == 1.0)
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1525 r = 1.;
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1526 else if (y > 0. && fabs(x) > 1.0)
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1527 r = y;
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1528 else if (y < 0. && fabs(x) < 1.0) {
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1529 r = -y; /* result is +inf */
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1530 if (x == 0.) /* 0**-inf: divide-by-zero */
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1531 errno = EDOM;
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1532 }
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1533 else
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1534 r = 0.;
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1535 }
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1536 }
46505
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1537 else {
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1538 /* let libm handle finite**finite */
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1539 errno = 0;
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1540 PyFPE_START_PROTECT("in math_pow", return 0);
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1541 r = pow(x, y);
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1542 PyFPE_END_PROTECT(r);
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1543 /* a NaN result should arise only from (-ve)**(finite
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1544 non-integer); in this case we want to raise ValueError. */
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1545 if (!Py_IS_FINITE(r)) {
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1546 if (Py_IS_NAN(r)) {
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1547 errno = EDOM;
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1548 }
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1549 /*
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1550 an infinite result here arises either from:
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1551 (A) (+/-0.)**negative (-> divide-by-zero)
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1552 (B) overflow of x**y with x and y finite
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1553 */
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1554 else if (Py_IS_INFINITY(r)) {
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1555 if (x == 0.)
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1556 errno = EDOM;
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1557 else
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1558 errno = ERANGE;
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1559 }
63965327b3ef Merged revisions 62386-62387,62389-62393,62396,62400-62402,62407,62409-62410,62412-62414,62418-62419 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 46477
diff changeset
1560 }
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1561 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1562
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1563 if (errno && is_error(r))
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1564 return NULL;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1565 else
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1566 return PyFloat_FromDouble(r);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1567 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1568
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1569 PyDoc_STRVAR(math_pow_doc,
57209
b354c1b6b476 Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 56270
diff changeset
1570 "pow(x, y)\n\nReturn x**y (x to the power of y).");
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1571
44441
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1572 static const double degToRad = Py_MATH_PI / 180.0;
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1573 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
1574
a4d675b8b53c Added degrees() and radians() to mathmodule. Closes patch 552452 and
Raymond Hettinger <python@rcn.com>
parents: 19758
diff changeset
1575 static PyObject *
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1576 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
1577 {
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1578 double x = PyFloat_AsDouble(arg);
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1579 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
1580 return NULL;
44441
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1581 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
1582 }
a4d675b8b53c Added degrees() and radians() to mathmodule. Closes patch 552452 and
Raymond Hettinger <python@rcn.com>
parents: 19758
diff changeset
1583
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
1584 PyDoc_STRVAR(math_degrees_doc,
57209
b354c1b6b476 Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 56270
diff changeset
1585 "degrees(x)\n\n\
b354c1b6b476 Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 56270
diff changeset
1586 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
1587
a4d675b8b53c Added degrees() and radians() to mathmodule. Closes patch 552452 and
Raymond Hettinger <python@rcn.com>
parents: 19758
diff changeset
1588 static PyObject *
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1589 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
1590 {
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1591 double x = PyFloat_AsDouble(arg);
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1592 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
1593 return NULL;
a4d675b8b53c Added degrees() and radians() to mathmodule. Closes patch 552452 and
Raymond Hettinger <python@rcn.com>
parents: 19758
diff changeset
1594 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
1595 }
a4d675b8b53c Added degrees() and radians() to mathmodule. Closes patch 552452 and
Raymond Hettinger <python@rcn.com>
parents: 19758
diff changeset
1596
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
1597 PyDoc_STRVAR(math_radians_doc,
57209
b354c1b6b476 Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 56270
diff changeset
1598 "radians(x)\n\n\
b354c1b6b476 Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 56270
diff changeset
1599 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
1600
44441
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1601 static PyObject *
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1602 math_isnan(PyObject *self, PyObject *arg)
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1603 {
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1604 double x = PyFloat_AsDouble(arg);
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1605 if (x == -1.0 && PyErr_Occurred())
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1606 return NULL;
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1607 return PyBool_FromLong((long)Py_IS_NAN(x));
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1608 }
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1609
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1610 PyDoc_STRVAR(math_isnan_doc,
57209
b354c1b6b476 Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 56270
diff changeset
1611 "isnan(x) -> bool\n\n\
b354c1b6b476 Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 56270
diff changeset
1612 Check if float x is not a number (NaN).");
44441
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1613
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1614 static PyObject *
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1615 math_isinf(PyObject *self, PyObject *arg)
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1616 {
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1617 double x = PyFloat_AsDouble(arg);
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1618 if (x == -1.0 && PyErr_Occurred())
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1619 return NULL;
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1620 return PyBool_FromLong((long)Py_IS_INFINITY(x));
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1621 }
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1622
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1623 PyDoc_STRVAR(math_isinf_doc,
57209
b354c1b6b476 Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 56270
diff changeset
1624 "isinf(x) -> bool\n\n\
b354c1b6b476 Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 56270
diff changeset
1625 Check if float x is infinite (positive or negative).");
44441
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1626
4635
49745ddb4f69 Renamed
Barry Warsaw <barry@python.org>
parents: 4503
diff changeset
1627 static PyMethodDef math_methods[] = {
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1628 {"acos", math_acos, METH_O, math_acos_doc},
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1629 {"acosh", math_acosh, METH_O, math_acosh_doc},
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1630 {"asin", math_asin, METH_O, math_asin_doc},
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1631 {"asinh", math_asinh, METH_O, math_asinh_doc},
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1632 {"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
1633 {"atan2", math_atan2, METH_VARARGS, math_atan2_doc},
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1634 {"atanh", math_atanh, METH_O, math_atanh_doc},
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1635 {"ceil", math_ceil, METH_O, math_ceil_doc},
44441
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1636 {"copysign", math_copysign, METH_VARARGS, math_copysign_doc},
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1637 {"cos", math_cos, METH_O, math_cos_doc},
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1638 {"cosh", math_cosh, METH_O, math_cosh_doc},
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1639 {"degrees", math_degrees, METH_O, math_degrees_doc},
57770
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
1640 {"erf", math_erf, METH_O, math_erf_doc},
1e8164b5f36d Merged revisions 76878 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57758
diff changeset
1641 {"erfc", math_erfc, METH_O, math_erfc_doc},
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1642 {"exp", math_exp, METH_O, math_exp_doc},
57758
b45ca11b9a3e Merged revisions 76861 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57660
diff changeset
1643 {"expm1", math_expm1, METH_O, math_expm1_doc},
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1644 {"fabs", math_fabs, METH_O, math_fabs_doc},
47562
bd584f121c4b Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
Georg Brandl <georg@python.org>
parents: 47559
diff changeset
1645 {"factorial", math_factorial, METH_O, math_factorial_doc},
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1646 {"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
1647 {"fmod", math_fmod, METH_VARARGS, math_fmod_doc},
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1648 {"frexp", math_frexp, METH_O, math_frexp_doc},
48606
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1649 {"fsum", math_fsum, METH_O, math_fsum_doc},
56270
47b82fbdc2bb Merged revisions 75117 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50250
diff changeset
1650 {"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
1651 {"hypot", math_hypot, METH_VARARGS, math_hypot_doc},
44441
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1652 {"isinf", math_isinf, METH_O, math_isinf_doc},
b91ca87e6f32 Merged revisions 59666-59679 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44351
diff changeset
1653 {"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
1654 {"ldexp", math_ldexp, METH_VARARGS, math_ldexp_doc},
57660
7cb73e7c176d Merged revisions 76755 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 57209
diff changeset
1655 {"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
1656 {"log", math_log, METH_VARARGS, math_log_doc},
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1657 {"log1p", math_log1p, METH_O, math_log1p_doc},
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1658 {"log10", math_log10, METH_O, math_log10_doc},
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1659 {"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
1660 {"pow", math_pow, METH_VARARGS, math_pow_doc},
40450
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1661 {"radians", math_radians, METH_O, math_radians_doc},
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1662 {"sin", math_sin, METH_O, math_sin_doc},
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1663 {"sinh", math_sinh, METH_O, math_sinh_doc},
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1664 {"sqrt", math_sqrt, METH_O, math_sqrt_doc},
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1665 {"tan", math_tan, METH_O, math_tan_doc},
cc992d75d5b3 Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents: 37191
diff changeset
1666 {"tanh", math_tanh, METH_O, math_tanh_doc},
48606
f121a963ab69 Merged revisions 65258,65292,65299,65308-65309,65315,65326 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 48407
diff changeset
1667 {"trunc", math_trunc, METH_O, math_trunc_doc},
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1668 {NULL, NULL} /* sentinel */
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1669 };
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1670
9593
f22f769bf3d9 Added Doc strings -- by Chris Petrilli.
Guido van Rossum <guido@python.org>
parents: 9588
diff changeset
1671
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23427
diff changeset
1672 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
1673 "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
1674 "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
1675
47580
94f64f11fdd0 Implement PEP 3121: new module initialization and finalization API.
Martin v. Löwis <martin@v.loewis.de>
parents: 47562
diff changeset
1676
94f64f11fdd0 Implement PEP 3121: new module initialization and finalization API.
Martin v. Löwis <martin@v.loewis.de>
parents: 47562
diff changeset
1677 static struct PyModuleDef mathmodule = {
94f64f11fdd0 Implement PEP 3121: new module initialization and finalization API.
Martin v. Löwis <martin@v.loewis.de>
parents: 47562
diff changeset
1678 PyModuleDef_HEAD_INIT,
94f64f11fdd0 Implement PEP 3121: new module initialization and finalization API.
Martin v. Löwis <martin@v.loewis.de>
parents: 47562
diff changeset
1679 "math",
94f64f11fdd0 Implement PEP 3121: new module initialization and finalization API.
Martin v. Löwis <martin@v.loewis.de>
parents: 47562
diff changeset
1680 module_doc,
94f64f11fdd0 Implement PEP 3121: new module initialization and finalization API.
Martin v. Löwis <martin@v.loewis.de>
parents: 47562
diff changeset
1681 -1,
94f64f11fdd0 Implement PEP 3121: new module initialization and finalization API.
Martin v. Löwis <martin@v.loewis.de>
parents: 47562
diff changeset
1682 math_methods,
94f64f11fdd0 Implement PEP 3121: new module initialization and finalization API.
Martin v. Löwis <martin@v.loewis.de>
parents: 47562
diff changeset
1683 NULL,
94f64f11fdd0 Implement PEP 3121: new module initialization and finalization API.
Martin v. Löwis <martin@v.loewis.de>
parents: 47562
diff changeset
1684 NULL,
94f64f11fdd0 Implement PEP 3121: new module initialization and finalization API.
Martin v. Löwis <martin@v.loewis.de>
parents: 47562
diff changeset
1685 NULL,
94f64f11fdd0 Implement PEP 3121: new module initialization and finalization API.
Martin v. Löwis <martin@v.loewis.de>
parents: 47562
diff changeset
1686 NULL
94f64f11fdd0 Implement PEP 3121: new module initialization and finalization API.
Martin v. Löwis <martin@v.loewis.de>
parents: 47562
diff changeset
1687 };
94f64f11fdd0 Implement PEP 3121: new module initialization and finalization API.
Martin v. Löwis <martin@v.loewis.de>
parents: 47562
diff changeset
1688
24471
f66b3a3509c7 Excise DL_EXPORT/DL_IMPORT from Modules/*. Required adding a prototype
Mark Hammond <mhammond@skippinet.com.au>
parents: 23832
diff changeset
1689 PyMODINIT_FUNC
47580
94f64f11fdd0 Implement PEP 3121: new module initialization and finalization API.
Martin v. Löwis <martin@v.loewis.de>
parents: 47562
diff changeset
1690 PyInit_math(void)
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1691 {
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1692 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
1693
47580
94f64f11fdd0 Implement PEP 3121: new module initialization and finalization API.
Martin v. Löwis <martin@v.loewis.de>
parents: 47562
diff changeset
1694 m = PyModule_Create(&mathmodule);
36324
1af7f719ed28 Check return result from Py_InitModule*(). This API can fail.
Neal Norwitz <nnorwitz@gmail.com>
parents: 34872
diff changeset
1695 if (m == NULL)
1af7f719ed28 Check return result from Py_InitModule*(). This API can fail.
Neal Norwitz <nnorwitz@gmail.com>
parents: 34872
diff changeset
1696 goto finally;
4752
7367fb107108 Better error checking in initmath().
Barry Warsaw <barry@python.org>
parents: 4635
diff changeset
1697
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1698 PyModule_AddObject(m, "pi", PyFloat_FromDouble(Py_MATH_PI));
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1699 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
1700
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45134
diff changeset
1701 finally:
47580
94f64f11fdd0 Implement PEP 3121: new module initialization and finalization API.
Martin v. Löwis <martin@v.loewis.de>
parents: 47562
diff changeset
1702 return m;
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1703 }