blob: 42709ee09a30df298eea05e2201f22c61e5452bf [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 Rossumb18618d2000-05-03 23:44:39 +0000169 register PyComplexObject *op;
170
171 /* PyObject_New is inlined */
172 op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject));
Guido van Rossumf9fca921996-01-12 00:47:05 +0000173 if (op == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000174 return PyErr_NoMemory();
Guido van Rossumb18618d2000-05-03 23:44:39 +0000175 PyObject_INIT(op, &PyComplex_Type);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000176 op->cval = cval;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000177 return (PyObject *) op;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000178}
179
180PyObject *
Guido van Rossum926518b1996-08-19 19:30:45 +0000181PyComplex_FromDoubles(real, imag)
182 double real, imag;
183{
184 Py_complex c;
185 c.real = real;
186 c.imag = imag;
187 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000188}
189
190double
Guido van Rossum926518b1996-08-19 19:30:45 +0000191PyComplex_RealAsDouble(op)
192 PyObject *op;
193{
194 if (PyComplex_Check(op)) {
195 return ((PyComplexObject *)op)->cval.real;
196 } else {
197 return PyFloat_AsDouble(op);
198 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000199}
200
201double
Guido van Rossum926518b1996-08-19 19:30:45 +0000202PyComplex_ImagAsDouble(op)
203 PyObject *op;
204{
205 if (PyComplex_Check(op)) {
206 return ((PyComplexObject *)op)->cval.imag;
207 } else {
208 return 0.0;
209 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000210}
211
Guido van Rossum9e720e31996-07-21 02:31:35 +0000212Py_complex
Guido van Rossum926518b1996-08-19 19:30:45 +0000213PyComplex_AsCComplex(op)
214 PyObject *op;
215{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000216 Py_complex cv;
Guido van Rossumcf3d1081996-01-12 01:21:14 +0000217 if (PyComplex_Check(op)) {
218 return ((PyComplexObject *)op)->cval;
219 } else {
220 cv.real = PyFloat_AsDouble(op);
221 cv.imag = 0.;
222 return cv;
223 }
224}
225
Guido van Rossumf9fca921996-01-12 00:47:05 +0000226static void
227complex_dealloc(op)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000228 PyObject *op;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000229{
Guido van Rossumb18618d2000-05-03 23:44:39 +0000230 PyObject_DEL(op);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000231}
232
233
Guido van Rossum363078a1996-05-24 20:45:01 +0000234static void
Guido van Rossumf9fca921996-01-12 00:47:05 +0000235complex_buf_repr(buf, v)
236 char *buf;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000237 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000238{
239 if (v->cval.real == 0.)
Guido van Rossum72418791996-01-25 16:21:31 +0000240 sprintf(buf, "%.12gj", v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000241 else
Guido van Rossum72418791996-01-25 16:21:31 +0000242 sprintf(buf, "(%.12g%+.12gj)", v->cval.real, v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000243}
244
245static int
246complex_print(v, fp, flags)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000247 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000248 FILE *fp;
249 int flags; /* Not used but required by interface */
250{
251 char buf[100];
252 complex_buf_repr(buf, v);
253 fputs(buf, fp);
254 return 0;
255}
256
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000257static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000258complex_repr(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000259 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000260{
261 char buf[100];
262 complex_buf_repr(buf, v);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000263 return PyString_FromString(buf);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000264}
265
266static int
267complex_compare(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000268 PyComplexObject *v, *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000269{
270/* Note: "greater" and "smaller" have no meaning for complex numbers,
271 but Python requires that they be defined nevertheless. */
Guido van Rossum926518b1996-08-19 19:30:45 +0000272 Py_complex i, j;
273 i = v->cval;
274 j = w->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000275 if (i.real == j.real && i.imag == j.imag)
276 return 0;
277 else if (i.real != j.real)
278 return (i.real < j.real) ? -1 : 1;
279 else
280 return (i.imag < j.imag) ? -1 : 1;
281}
282
283static long
284complex_hash(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000285 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000286{
287 double intpart, fractpart;
288 int expo;
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000289 long hipart, x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000290 /* This is designed so that Python numbers with the same
291 value hash to the same value, otherwise comparisons
292 of mapping keys will turn out weird */
293
294#ifdef MPW /* MPW C modf expects pointer to extended as second argument */
295{
296 extended e;
297 fractpart = modf(v->cval.real, &e);
298 intpart = e;
299}
300#else
301 fractpart = modf(v->cval.real, &intpart);
302#endif
303
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000304 if (fractpart == 0.0 && v->cval.imag == 0.0) {
Guido van Rossumf9fca921996-01-12 00:47:05 +0000305 if (intpart > 0x7fffffffL || -intpart > 0x7fffffffL) {
306 /* Convert to long int and use its hash... */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000307 PyObject *w = PyLong_FromDouble(v->cval.real);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000308 if (w == NULL)
309 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000310 x = PyObject_Hash(w);
311 Py_DECREF(w);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000312 return x;
313 }
314 x = (long)intpart;
315 }
316 else {
317 fractpart = frexp(fractpart, &expo);
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000318 fractpart = fractpart * 2147483648.0; /* 2**31 */
319 hipart = (long)fractpart; /* Take the top 32 bits */
320 fractpart = (fractpart - (double)hipart) * 2147483648.0;
321 /* Get the next 32 bits */
322 x = hipart + (long)fractpart + (long)intpart + (expo << 15);
323 /* Combine everything */
324
325 if (v->cval.imag != 0.0) { /* Hash the imaginary part */
326 /* XXX Note that this hashes complex(x, y)
327 to the same value as complex(y, x).
328 Still better than it used to be :-) */
329#ifdef MPW
330 {
331 extended e;
332 fractpart = modf(v->cval.imag, &e);
333 intpart = e;
334 }
335#else
336 fractpart = modf(v->cval.imag, &intpart);
337#endif
338 fractpart = frexp(fractpart, &expo);
339 fractpart = fractpart * 2147483648.0; /* 2**31 */
340 hipart = (long)fractpart; /* Take the top 32 bits */
341 fractpart =
342 (fractpart - (double)hipart) * 2147483648.0;
343 /* Get the next 32 bits */
344 x ^= hipart + (long)fractpart +
345 (long)intpart + (expo << 15);
346 /* Combine everything */
347 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000348 }
349 if (x == -1)
350 x = -2;
351 return x;
352}
353
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000354static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000355complex_add(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000356 PyComplexObject *v;
357 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000358{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000359 Py_complex result;
360 PyFPE_START_PROTECT("complex_add", return 0)
361 result = c_sum(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000362 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000363 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000364}
365
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000366static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000367complex_sub(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000368 PyComplexObject *v;
369 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000370{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000371 Py_complex result;
372 PyFPE_START_PROTECT("complex_sub", return 0)
373 result = c_diff(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000374 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000375 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000376}
377
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000378static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000379complex_mul(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000380 PyComplexObject *v;
381 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000382{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000383 Py_complex result;
384 PyFPE_START_PROTECT("complex_mul", return 0)
385 result = c_prod(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000386 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000387 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000388}
389
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000390static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000391complex_div(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000392 PyComplexObject *v;
393 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000394{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000395 Py_complex quot;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000396 PyFPE_START_PROTECT("complex_div", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000397 errno = 0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000398 quot = c_quot(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000399 PyFPE_END_PROTECT(quot)
Guido van Rossum96783941997-05-20 18:21:34 +0000400 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000401 PyErr_SetString(PyExc_ZeroDivisionError, "complex division");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000402 return NULL;
403 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000404 return PyComplex_FromCComplex(quot);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000405}
406
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000407static PyObject *
Guido van Rossumee09fc11996-09-11 13:55:55 +0000408complex_remainder(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000409 PyComplexObject *v;
410 PyComplexObject *w;
Guido van Rossumee09fc11996-09-11 13:55:55 +0000411{
Guido van Rossum3be12e91996-09-12 20:56:18 +0000412 Py_complex div, mod;
Guido van Rossum96783941997-05-20 18:21:34 +0000413 errno = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000414 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
Guido van Rossum96783941997-05-20 18:21:34 +0000415 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000416 PyErr_SetString(PyExc_ZeroDivisionError, "complex remainder");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000417 return NULL;
418 }
419 div.real = floor(div.real); /* Use the floor of the real part. */
420 div.imag = 0.0;
421 mod = c_diff(v->cval, c_prod(w->cval, div));
422
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000423 return PyComplex_FromCComplex(mod);
Guido van Rossumee09fc11996-09-11 13:55:55 +0000424}
425
Guido van Rossumee09fc11996-09-11 13:55:55 +0000426
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000427static PyObject *
Guido van Rossum3be12e91996-09-12 20:56:18 +0000428complex_divmod(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000429 PyComplexObject *v;
430 PyComplexObject *w;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000431{
432 Py_complex div, mod;
433 PyObject *d, *m, *z;
Guido van Rossum96783941997-05-20 18:21:34 +0000434 errno = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000435 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
Guido van Rossum96783941997-05-20 18:21:34 +0000436 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000437 PyErr_SetString(PyExc_ZeroDivisionError, "complex divmod()");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000438 return NULL;
439 }
440 div.real = floor(div.real); /* Use the floor of the real part. */
441 div.imag = 0.0;
442 mod = c_diff(v->cval, c_prod(w->cval, div));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000443 d = PyComplex_FromCComplex(div);
444 m = PyComplex_FromCComplex(mod);
445 z = Py_BuildValue("(OO)", d, m);
Guido van Rossum3be12e91996-09-12 20:56:18 +0000446 Py_XDECREF(d);
447 Py_XDECREF(m);
448 return z;
449}
Guido van Rossumf9fca921996-01-12 00:47:05 +0000450
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000451static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000452complex_pow(v, w, z)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000453 PyComplexObject *v;
454 PyObject *w;
455 PyComplexObject *z;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000456{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000457 Py_complex p;
458 Py_complex exponent;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000459 long int_exponent;
460
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000461 if ((PyObject *)z!=Py_None) {
462 PyErr_SetString(PyExc_ValueError, "complex modulo");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000463 return NULL;
464 }
465
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000466 PyFPE_START_PROTECT("complex_pow", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000467 errno = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000468 exponent = ((PyComplexObject*)w)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000469 int_exponent = (long)exponent.real;
470 if (exponent.imag == 0. && exponent.real == int_exponent)
471 p = c_powi(v->cval,int_exponent);
472 else
473 p = c_pow(v->cval,exponent);
474
Guido van Rossum45b83911997-03-14 04:32:50 +0000475 PyFPE_END_PROTECT(p)
Guido van Rossum96783941997-05-20 18:21:34 +0000476 if (errno == ERANGE) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000477 PyErr_SetString(PyExc_ValueError,
478 "0.0 to a negative or complex power");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000479 return NULL;
480 }
481
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000482 return PyComplex_FromCComplex(p);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000483}
484
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000485static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000486complex_neg(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000487 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000488{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000489 Py_complex neg;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000490 neg.real = -v->cval.real;
491 neg.imag = -v->cval.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000492 return PyComplex_FromCComplex(neg);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000493}
494
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000495static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000496complex_pos(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000497 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000498{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000499 Py_INCREF(v);
500 return (PyObject *)v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000501}
502
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000503static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000504complex_abs(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000505 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000506{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000507 double result;
508 PyFPE_START_PROTECT("complex_abs", return 0)
509 result = hypot(v->cval.real,v->cval.imag);
Guido van Rossum45b83911997-03-14 04:32:50 +0000510 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000511 return PyFloat_FromDouble(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000512}
513
514static int
515complex_nonzero(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000516 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000517{
Guido van Rossum3bbef601999-01-25 19:42:19 +0000518 return v->cval.real != 0.0 || v->cval.imag != 0.0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000519}
520
521static int
522complex_coerce(pv, pw)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000523 PyObject **pv;
524 PyObject **pw;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000525{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000526 Py_complex cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000527 cval.imag = 0.;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000528 if (PyInt_Check(*pw)) {
529 cval.real = (double)PyInt_AsLong(*pw);
530 *pw = PyComplex_FromCComplex(cval);
531 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000532 return 0;
533 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000534 else if (PyLong_Check(*pw)) {
535 cval.real = PyLong_AsDouble(*pw);
536 *pw = PyComplex_FromCComplex(cval);
537 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000538 return 0;
539 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000540 else if (PyFloat_Check(*pw)) {
541 cval.real = PyFloat_AsDouble(*pw);
542 *pw = PyComplex_FromCComplex(cval);
543 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000544 return 0;
545 }
546 return 1; /* Can't do it */
547}
548
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000549static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000550complex_int(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000551 PyObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000552{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000553 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000554 "can't convert complex to int; use e.g. int(abs(z))");
555 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000556}
557
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000558static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000559complex_long(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000560 PyObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000561{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000562 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000563 "can't convert complex to long; use e.g. long(abs(z))");
564 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000565}
566
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000567static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000568complex_float(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000569 PyObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000570{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000571 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000572 "can't convert complex to float; use e.g. abs(z)");
573 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000574}
575
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000576static PyObject *
Guido van Rossum8530ef61998-05-07 16:29:10 +0000577complex_conjugate(self, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000578 PyObject *self;
Guido van Rossum8530ef61998-05-07 16:29:10 +0000579 PyObject *args;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000580{
Guido van Rossum926518b1996-08-19 19:30:45 +0000581 Py_complex c;
Guido van Rossum43713e52000-02-29 13:59:29 +0000582 if (!PyArg_ParseTuple(args, ":conjugate"))
Guido van Rossum8530ef61998-05-07 16:29:10 +0000583 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000584 c = ((PyComplexObject *)self)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000585 c.imag = -c.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000586 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000587}
588
589static PyMethodDef complex_methods[] = {
Guido van Rossum8530ef61998-05-07 16:29:10 +0000590 {"conjugate", complex_conjugate, 1},
Guido van Rossumf9fca921996-01-12 00:47:05 +0000591 {NULL, NULL} /* sentinel */
592};
593
594
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000595static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000596complex_getattr(self, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000597 PyComplexObject *self;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000598 char *name;
599{
Guido van Rossumf9fca921996-01-12 00:47:05 +0000600 if (strcmp(name, "real") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000601 return (PyObject *)PyFloat_FromDouble(self->cval.real);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000602 else if (strcmp(name, "imag") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000603 return (PyObject *)PyFloat_FromDouble(self->cval.imag);
Guido van Rossumc054d701997-04-01 03:12:33 +0000604 else if (strcmp(name, "__members__") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000605 return Py_BuildValue("[ss]", "imag", "real");
606 return Py_FindMethod(complex_methods, (PyObject *)self, name);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000607}
608
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000609static PyNumberMethods complex_as_number = {
Guido van Rossumf9fca921996-01-12 00:47:05 +0000610 (binaryfunc)complex_add, /*nb_add*/
611 (binaryfunc)complex_sub, /*nb_subtract*/
612 (binaryfunc)complex_mul, /*nb_multiply*/
613 (binaryfunc)complex_div, /*nb_divide*/
Guido van Rossumee09fc11996-09-11 13:55:55 +0000614 (binaryfunc)complex_remainder, /*nb_remainder*/
615 (binaryfunc)complex_divmod, /*nb_divmod*/
Guido van Rossumf9fca921996-01-12 00:47:05 +0000616 (ternaryfunc)complex_pow, /*nb_power*/
617 (unaryfunc)complex_neg, /*nb_negative*/
618 (unaryfunc)complex_pos, /*nb_positive*/
619 (unaryfunc)complex_abs, /*nb_absolute*/
620 (inquiry)complex_nonzero, /*nb_nonzero*/
621 0, /*nb_invert*/
622 0, /*nb_lshift*/
623 0, /*nb_rshift*/
624 0, /*nb_and*/
625 0, /*nb_xor*/
626 0, /*nb_or*/
627 (coercion)complex_coerce, /*nb_coerce*/
628 (unaryfunc)complex_int, /*nb_int*/
629 (unaryfunc)complex_long, /*nb_long*/
630 (unaryfunc)complex_float, /*nb_float*/
631 0, /*nb_oct*/
632 0, /*nb_hex*/
633};
634
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000635PyTypeObject PyComplex_Type = {
636 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000637 0,
638 "complex",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000639 sizeof(PyComplexObject),
Guido van Rossumf9fca921996-01-12 00:47:05 +0000640 0,
641 (destructor)complex_dealloc, /*tp_dealloc*/
642 (printfunc)complex_print, /*tp_print*/
643 (getattrfunc)complex_getattr, /*tp_getattr*/
644 0, /*tp_setattr*/
645 (cmpfunc)complex_compare, /*tp_compare*/
646 (reprfunc)complex_repr, /*tp_repr*/
647 &complex_as_number, /*tp_as_number*/
648 0, /*tp_as_sequence*/
649 0, /*tp_as_mapping*/
650 (hashfunc)complex_hash, /*tp_hash*/
651};
652
653#endif