Mercurial > cpython-lru_cache-weakref
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 |
| rev | line source |
|---|---|
| 6 | 1 /* Math module -- standard C math library functions, pi and e */ |
| 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 | 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 | 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 | 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 | 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 | 680 return NULL; |
| 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 | 763 } |
| 764 | |
| 4635 | 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 | 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 | 775 return NULL; |
| 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 | 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 | 796 } |
| 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 1668 {NULL, NULL} /* sentinel */ |
| 1669 }; | |
| 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 | 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 | 1703 } |
