blob: e8447bb7c58926536350837fd4bfdabfe36c1293 [file] [log] [blame]
Guido van Rossum96783941997-05-20 18:21:34 +00001/***********************************************************
2Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
16
17While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
29
30******************************************************************/
31
Guido van Rossumf9fca921996-01-12 00:47:05 +000032/* Complex object implementation */
33
34/* Borrows heavily from floatobject.c */
35
Guido van Rossum96783941997-05-20 18:21:34 +000036/* Submitted by Jim Hugunin */
37
Guido van Rossumf9fca921996-01-12 00:47:05 +000038#ifndef WITHOUT_COMPLEX
39
Guido van Rossumc0b618a1997-05-02 03:12:38 +000040#include "Python.h"
Guido van Rossumf9fca921996-01-12 00:47:05 +000041#include "mymath.h"
42
Guido van Rossumf9fca921996-01-12 00:47:05 +000043#ifdef HAVE_LIMITS_H
44#include <limits.h>
45#endif
46
Guido van Rossumf9fca921996-01-12 00:47:05 +000047
48/* elementary operations on complex numbers */
49
Guido van Rossum9e720e31996-07-21 02:31:35 +000050static Py_complex c_1 = {1., 0.};
Guido van Rossumf9fca921996-01-12 00:47:05 +000051
Guido van Rossum9e720e31996-07-21 02:31:35 +000052Py_complex c_sum(a,b)
53 Py_complex a,b;
Guido van Rossumf9fca921996-01-12 00:47:05 +000054{
Guido van Rossum9e720e31996-07-21 02:31:35 +000055 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000056 r.real = a.real + b.real;
57 r.imag = a.imag + b.imag;
58 return r;
59}
60
Guido van Rossum9e720e31996-07-21 02:31:35 +000061Py_complex c_diff(a,b)
62 Py_complex a,b;
Guido van Rossumf9fca921996-01-12 00:47:05 +000063{
Guido van Rossum9e720e31996-07-21 02:31:35 +000064 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000065 r.real = a.real - b.real;
66 r.imag = a.imag - b.imag;
67 return r;
68}
69
Guido van Rossum9e720e31996-07-21 02:31:35 +000070Py_complex c_neg(a)
71 Py_complex a;
Guido van Rossumf9fca921996-01-12 00:47:05 +000072{
Guido van Rossum9e720e31996-07-21 02:31:35 +000073 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000074 r.real = -a.real;
75 r.imag = -a.imag;
76 return r;
77}
78
Guido van Rossum9e720e31996-07-21 02:31:35 +000079Py_complex c_prod(a,b)
80 Py_complex a,b;
Guido van Rossumf9fca921996-01-12 00:47:05 +000081{
Guido van Rossum9e720e31996-07-21 02:31:35 +000082 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000083 r.real = a.real*b.real - a.imag*b.imag;
84 r.imag = a.real*b.imag + a.imag*b.real;
85 return r;
86}
87
Guido van Rossum9e720e31996-07-21 02:31:35 +000088Py_complex c_quot(a,b)
89 Py_complex a,b;
Guido van Rossumf9fca921996-01-12 00:47:05 +000090{
Guido van Rossum9e720e31996-07-21 02:31:35 +000091 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000092 double d = b.real*b.real + b.imag*b.imag;
93 if (d == 0.)
Guido van Rossum96783941997-05-20 18:21:34 +000094 errno = EDOM;
Guido van Rossumf9fca921996-01-12 00:47:05 +000095 r.real = (a.real*b.real + a.imag*b.imag)/d;
96 r.imag = (a.imag*b.real - a.real*b.imag)/d;
97 return r;
98}
99
Guido van Rossum9e720e31996-07-21 02:31:35 +0000100Py_complex c_pow(a,b)
101 Py_complex a,b;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000102{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000103 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000104 double vabs,len,at,phase;
105 if (b.real == 0. && b.imag == 0.) {
106 r.real = 1.;
107 r.imag = 0.;
108 }
109 else if (a.real == 0. && a.imag == 0.) {
110 if (b.imag != 0. || b.real < 0.)
Guido van Rossum96783941997-05-20 18:21:34 +0000111 errno = ERANGE;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000112 r.real = 0.;
113 r.imag = 0.;
114 }
115 else {
116 vabs = hypot(a.real,a.imag);
117 len = pow(vabs,b.real);
118 at = atan2(a.imag, a.real);
119 phase = at*b.real;
120 if (b.imag != 0.0) {
121 len /= exp(at*b.imag);
122 phase += b.imag*log(vabs);
123 }
124 r.real = len*cos(phase);
125 r.imag = len*sin(phase);
126 }
127 return r;
128}
129
Guido van Rossum9e720e31996-07-21 02:31:35 +0000130static Py_complex c_powu(x, n)
131 Py_complex x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000132 long n;
133{
Guido van Rossum926518b1996-08-19 19:30:45 +0000134 Py_complex r, p;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000135 long mask = 1;
Guido van Rossum926518b1996-08-19 19:30:45 +0000136 r = c_1;
137 p = x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000138 while (mask > 0 && n >= mask) {
139 if (n & mask)
140 r = c_prod(r,p);
141 mask <<= 1;
142 p = c_prod(p,p);
143 }
144 return r;
145}
146
Guido van Rossum9e720e31996-07-21 02:31:35 +0000147static Py_complex c_powi(x, n)
148 Py_complex x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000149 long n;
150{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000151 Py_complex cn;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000152
153 if (n > 100 || n < -100) {
154 cn.real = (double) n;
155 cn.imag = 0.;
156 return c_pow(x,cn);
157 }
158 else if (n > 0)
159 return c_powu(x,n);
160 else
161 return c_quot(c_1,c_powu(x,-n));
162
163}
164
165PyObject *
Guido van Rossum926518b1996-08-19 19:30:45 +0000166PyComplex_FromCComplex(cval)
167 Py_complex cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000168{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000169 register PyComplexObject *op =
170 (PyComplexObject *) malloc(sizeof(PyComplexObject));
Guido van Rossumf9fca921996-01-12 00:47:05 +0000171 if (op == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000172 return PyErr_NoMemory();
173 op->ob_type = &PyComplex_Type;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000174 op->cval = cval;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000175 _Py_NewReference(op);
176 return (PyObject *) op;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000177}
178
179PyObject *
Guido van Rossum926518b1996-08-19 19:30:45 +0000180PyComplex_FromDoubles(real, imag)
181 double real, imag;
182{
183 Py_complex c;
184 c.real = real;
185 c.imag = imag;
186 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000187}
188
189double
Guido van Rossum926518b1996-08-19 19:30:45 +0000190PyComplex_RealAsDouble(op)
191 PyObject *op;
192{
193 if (PyComplex_Check(op)) {
194 return ((PyComplexObject *)op)->cval.real;
195 } else {
196 return PyFloat_AsDouble(op);
197 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000198}
199
200double
Guido van Rossum926518b1996-08-19 19:30:45 +0000201PyComplex_ImagAsDouble(op)
202 PyObject *op;
203{
204 if (PyComplex_Check(op)) {
205 return ((PyComplexObject *)op)->cval.imag;
206 } else {
207 return 0.0;
208 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000209}
210
Guido van Rossum9e720e31996-07-21 02:31:35 +0000211Py_complex
Guido van Rossum926518b1996-08-19 19:30:45 +0000212PyComplex_AsCComplex(op)
213 PyObject *op;
214{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000215 Py_complex cv;
Guido van Rossumcf3d1081996-01-12 01:21:14 +0000216 if (PyComplex_Check(op)) {
217 return ((PyComplexObject *)op)->cval;
218 } else {
219 cv.real = PyFloat_AsDouble(op);
220 cv.imag = 0.;
221 return cv;
222 }
223}
224
Guido van Rossumf9fca921996-01-12 00:47:05 +0000225static void
226complex_dealloc(op)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000227 PyObject *op;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000228{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000229 PyMem_DEL(op);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000230}
231
232
Guido van Rossum363078a1996-05-24 20:45:01 +0000233static void
Guido van Rossumf9fca921996-01-12 00:47:05 +0000234complex_buf_repr(buf, v)
235 char *buf;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000236 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000237{
238 if (v->cval.real == 0.)
Guido van Rossum72418791996-01-25 16:21:31 +0000239 sprintf(buf, "%.12gj", v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000240 else
Guido van Rossum72418791996-01-25 16:21:31 +0000241 sprintf(buf, "(%.12g%+.12gj)", v->cval.real, v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000242}
243
244static int
245complex_print(v, fp, flags)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000246 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000247 FILE *fp;
248 int flags; /* Not used but required by interface */
249{
250 char buf[100];
251 complex_buf_repr(buf, v);
252 fputs(buf, fp);
253 return 0;
254}
255
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000256static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000257complex_repr(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000258 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000259{
260 char buf[100];
261 complex_buf_repr(buf, v);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000262 return PyString_FromString(buf);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000263}
264
265static int
266complex_compare(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000267 PyComplexObject *v, *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000268{
269/* Note: "greater" and "smaller" have no meaning for complex numbers,
270 but Python requires that they be defined nevertheless. */
Guido van Rossum926518b1996-08-19 19:30:45 +0000271 Py_complex i, j;
272 i = v->cval;
273 j = w->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000274 if (i.real == j.real && i.imag == j.imag)
275 return 0;
276 else if (i.real != j.real)
277 return (i.real < j.real) ? -1 : 1;
278 else
279 return (i.imag < j.imag) ? -1 : 1;
280}
281
282static long
283complex_hash(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000284 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000285{
286 double intpart, fractpart;
287 int expo;
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000288 long hipart, x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000289 /* This is designed so that Python numbers with the same
290 value hash to the same value, otherwise comparisons
291 of mapping keys will turn out weird */
292
293#ifdef MPW /* MPW C modf expects pointer to extended as second argument */
294{
295 extended e;
296 fractpart = modf(v->cval.real, &e);
297 intpart = e;
298}
299#else
300 fractpart = modf(v->cval.real, &intpart);
301#endif
302
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000303 if (fractpart == 0.0 && v->cval.imag == 0.0) {
Guido van Rossumf9fca921996-01-12 00:47:05 +0000304 if (intpart > 0x7fffffffL || -intpart > 0x7fffffffL) {
305 /* Convert to long int and use its hash... */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000306 PyObject *w = PyLong_FromDouble(v->cval.real);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000307 if (w == NULL)
308 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000309 x = PyObject_Hash(w);
310 Py_DECREF(w);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000311 return x;
312 }
313 x = (long)intpart;
314 }
315 else {
316 fractpart = frexp(fractpart, &expo);
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000317 fractpart = fractpart * 2147483648.0; /* 2**31 */
318 hipart = (long)fractpart; /* Take the top 32 bits */
319 fractpart = (fractpart - (double)hipart) * 2147483648.0;
320 /* Get the next 32 bits */
321 x = hipart + (long)fractpart + (long)intpart + (expo << 15);
322 /* Combine everything */
323
324 if (v->cval.imag != 0.0) { /* Hash the imaginary part */
325 /* XXX Note that this hashes complex(x, y)
326 to the same value as complex(y, x).
327 Still better than it used to be :-) */
328#ifdef MPW
329 {
330 extended e;
331 fractpart = modf(v->cval.imag, &e);
332 intpart = e;
333 }
334#else
335 fractpart = modf(v->cval.imag, &intpart);
336#endif
337 fractpart = frexp(fractpart, &expo);
338 fractpart = fractpart * 2147483648.0; /* 2**31 */
339 hipart = (long)fractpart; /* Take the top 32 bits */
340 fractpart =
341 (fractpart - (double)hipart) * 2147483648.0;
342 /* Get the next 32 bits */
343 x ^= hipart + (long)fractpart +
344 (long)intpart + (expo << 15);
345 /* Combine everything */
346 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000347 }
348 if (x == -1)
349 x = -2;
350 return x;
351}
352
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000353static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000354complex_add(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000355 PyComplexObject *v;
356 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000357{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000358 Py_complex result;
359 PyFPE_START_PROTECT("complex_add", return 0)
360 result = c_sum(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000361 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000362 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000363}
364
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000365static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000366complex_sub(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000367 PyComplexObject *v;
368 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000369{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000370 Py_complex result;
371 PyFPE_START_PROTECT("complex_sub", return 0)
372 result = c_diff(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000373 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000374 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000375}
376
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000377static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000378complex_mul(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000379 PyComplexObject *v;
380 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000381{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000382 Py_complex result;
383 PyFPE_START_PROTECT("complex_mul", return 0)
384 result = c_prod(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000385 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000386 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000387}
388
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000389static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000390complex_div(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000391 PyComplexObject *v;
392 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000393{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000394 Py_complex quot;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000395 PyFPE_START_PROTECT("complex_div", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000396 errno = 0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000397 quot = c_quot(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000398 PyFPE_END_PROTECT(quot)
Guido van Rossum96783941997-05-20 18:21:34 +0000399 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000400 PyErr_SetString(PyExc_ZeroDivisionError, "complex division");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000401 return NULL;
402 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000403 return PyComplex_FromCComplex(quot);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000404}
405
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000406static PyObject *
Guido van Rossumee09fc11996-09-11 13:55:55 +0000407complex_remainder(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000408 PyComplexObject *v;
409 PyComplexObject *w;
Guido van Rossumee09fc11996-09-11 13:55:55 +0000410{
Guido van Rossum3be12e91996-09-12 20:56:18 +0000411 Py_complex div, mod;
Guido van Rossum96783941997-05-20 18:21:34 +0000412 errno = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000413 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
Guido van Rossum96783941997-05-20 18:21:34 +0000414 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000415 PyErr_SetString(PyExc_ZeroDivisionError, "complex remainder");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000416 return NULL;
417 }
418 div.real = floor(div.real); /* Use the floor of the real part. */
419 div.imag = 0.0;
420 mod = c_diff(v->cval, c_prod(w->cval, div));
421
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000422 return PyComplex_FromCComplex(mod);
Guido van Rossumee09fc11996-09-11 13:55:55 +0000423}
424
Guido van Rossumee09fc11996-09-11 13:55:55 +0000425
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000426static PyObject *
Guido van Rossum3be12e91996-09-12 20:56:18 +0000427complex_divmod(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000428 PyComplexObject *v;
429 PyComplexObject *w;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000430{
431 Py_complex div, mod;
432 PyObject *d, *m, *z;
Guido van Rossum96783941997-05-20 18:21:34 +0000433 errno = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000434 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
Guido van Rossum96783941997-05-20 18:21:34 +0000435 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000436 PyErr_SetString(PyExc_ZeroDivisionError, "complex divmod()");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000437 return NULL;
438 }
439 div.real = floor(div.real); /* Use the floor of the real part. */
440 div.imag = 0.0;
441 mod = c_diff(v->cval, c_prod(w->cval, div));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000442 d = PyComplex_FromCComplex(div);
443 m = PyComplex_FromCComplex(mod);
444 z = Py_BuildValue("(OO)", d, m);
Guido van Rossum3be12e91996-09-12 20:56:18 +0000445 Py_XDECREF(d);
446 Py_XDECREF(m);
447 return z;
448}
Guido van Rossumf9fca921996-01-12 00:47:05 +0000449
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000450static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000451complex_pow(v, w, z)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000452 PyComplexObject *v;
453 PyObject *w;
454 PyComplexObject *z;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000455{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000456 Py_complex p;
457 Py_complex exponent;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000458 long int_exponent;
459
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000460 if ((PyObject *)z!=Py_None) {
461 PyErr_SetString(PyExc_ValueError, "complex modulo");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000462 return NULL;
463 }
464
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000465 PyFPE_START_PROTECT("complex_pow", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000466 errno = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000467 exponent = ((PyComplexObject*)w)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000468 int_exponent = (long)exponent.real;
469 if (exponent.imag == 0. && exponent.real == int_exponent)
470 p = c_powi(v->cval,int_exponent);
471 else
472 p = c_pow(v->cval,exponent);
473
Guido van Rossum45b83911997-03-14 04:32:50 +0000474 PyFPE_END_PROTECT(p)
Guido van Rossum96783941997-05-20 18:21:34 +0000475 if (errno == ERANGE) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000476 PyErr_SetString(PyExc_ValueError,
477 "0.0 to a negative or complex power");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000478 return NULL;
479 }
480
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000481 return PyComplex_FromCComplex(p);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000482}
483
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000484static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000485complex_neg(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000486 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000487{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000488 Py_complex neg;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000489 neg.real = -v->cval.real;
490 neg.imag = -v->cval.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000491 return PyComplex_FromCComplex(neg);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000492}
493
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000494static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000495complex_pos(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000496 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000497{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000498 Py_INCREF(v);
499 return (PyObject *)v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000500}
501
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000502static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000503complex_abs(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000504 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000505{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000506 double result;
507 PyFPE_START_PROTECT("complex_abs", return 0)
508 result = hypot(v->cval.real,v->cval.imag);
Guido van Rossum45b83911997-03-14 04:32:50 +0000509 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000510 return PyFloat_FromDouble(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000511}
512
513static int
514complex_nonzero(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000515 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000516{
Guido van Rossum3bbef601999-01-25 19:42:19 +0000517 return v->cval.real != 0.0 || v->cval.imag != 0.0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000518}
519
520static int
521complex_coerce(pv, pw)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000522 PyObject **pv;
523 PyObject **pw;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000524{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000525 Py_complex cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000526 cval.imag = 0.;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000527 if (PyInt_Check(*pw)) {
528 cval.real = (double)PyInt_AsLong(*pw);
529 *pw = PyComplex_FromCComplex(cval);
530 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000531 return 0;
532 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000533 else if (PyLong_Check(*pw)) {
534 cval.real = PyLong_AsDouble(*pw);
535 *pw = PyComplex_FromCComplex(cval);
536 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000537 return 0;
538 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000539 else if (PyFloat_Check(*pw)) {
540 cval.real = PyFloat_AsDouble(*pw);
541 *pw = PyComplex_FromCComplex(cval);
542 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000543 return 0;
544 }
545 return 1; /* Can't do it */
546}
547
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000548static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000549complex_int(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000550 PyObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000551{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000552 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000553 "can't convert complex to int; use e.g. int(abs(z))");
554 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000555}
556
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000557static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000558complex_long(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000559 PyObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000560{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000561 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000562 "can't convert complex to long; use e.g. long(abs(z))");
563 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000564}
565
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000566static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000567complex_float(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000568 PyObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000569{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000570 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000571 "can't convert complex to float; use e.g. abs(z)");
572 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000573}
574
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000575static PyObject *
Guido van Rossum8530ef61998-05-07 16:29:10 +0000576complex_conjugate(self, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000577 PyObject *self;
Guido van Rossum8530ef61998-05-07 16:29:10 +0000578 PyObject *args;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000579{
Guido van Rossum926518b1996-08-19 19:30:45 +0000580 Py_complex c;
Guido van Rossum8530ef61998-05-07 16:29:10 +0000581 if (!PyArg_ParseTuple(args, ""))
582 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000583 c = ((PyComplexObject *)self)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000584 c.imag = -c.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000585 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000586}
587
588static PyMethodDef complex_methods[] = {
Guido van Rossum8530ef61998-05-07 16:29:10 +0000589 {"conjugate", complex_conjugate, 1},
Guido van Rossumf9fca921996-01-12 00:47:05 +0000590 {NULL, NULL} /* sentinel */
591};
592
593
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000594static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000595complex_getattr(self, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000596 PyComplexObject *self;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000597 char *name;
598{
Guido van Rossumf9fca921996-01-12 00:47:05 +0000599 if (strcmp(name, "real") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000600 return (PyObject *)PyFloat_FromDouble(self->cval.real);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000601 else if (strcmp(name, "imag") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000602 return (PyObject *)PyFloat_FromDouble(self->cval.imag);
Guido van Rossumc054d701997-04-01 03:12:33 +0000603 else if (strcmp(name, "__members__") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000604 return Py_BuildValue("[ss]", "imag", "real");
605 return Py_FindMethod(complex_methods, (PyObject *)self, name);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000606}
607
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000608static PyNumberMethods complex_as_number = {
Guido van Rossumf9fca921996-01-12 00:47:05 +0000609 (binaryfunc)complex_add, /*nb_add*/
610 (binaryfunc)complex_sub, /*nb_subtract*/
611 (binaryfunc)complex_mul, /*nb_multiply*/
612 (binaryfunc)complex_div, /*nb_divide*/
Guido van Rossumee09fc11996-09-11 13:55:55 +0000613 (binaryfunc)complex_remainder, /*nb_remainder*/
614 (binaryfunc)complex_divmod, /*nb_divmod*/
Guido van Rossumf9fca921996-01-12 00:47:05 +0000615 (ternaryfunc)complex_pow, /*nb_power*/
616 (unaryfunc)complex_neg, /*nb_negative*/
617 (unaryfunc)complex_pos, /*nb_positive*/
618 (unaryfunc)complex_abs, /*nb_absolute*/
619 (inquiry)complex_nonzero, /*nb_nonzero*/
620 0, /*nb_invert*/
621 0, /*nb_lshift*/
622 0, /*nb_rshift*/
623 0, /*nb_and*/
624 0, /*nb_xor*/
625 0, /*nb_or*/
626 (coercion)complex_coerce, /*nb_coerce*/
627 (unaryfunc)complex_int, /*nb_int*/
628 (unaryfunc)complex_long, /*nb_long*/
629 (unaryfunc)complex_float, /*nb_float*/
630 0, /*nb_oct*/
631 0, /*nb_hex*/
632};
633
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000634PyTypeObject PyComplex_Type = {
635 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000636 0,
637 "complex",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000638 sizeof(PyComplexObject),
Guido van Rossumf9fca921996-01-12 00:47:05 +0000639 0,
640 (destructor)complex_dealloc, /*tp_dealloc*/
641 (printfunc)complex_print, /*tp_print*/
642 (getattrfunc)complex_getattr, /*tp_getattr*/
643 0, /*tp_setattr*/
644 (cmpfunc)complex_compare, /*tp_compare*/
645 (reprfunc)complex_repr, /*tp_repr*/
646 &complex_as_number, /*tp_as_number*/
647 0, /*tp_as_sequence*/
648 0, /*tp_as_mapping*/
649 (hashfunc)complex_hash, /*tp_hash*/
650};
651
652#endif