blob: 1a15a27ebd49f2943629f0dcc63a23758eccc007 [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;
Fred Drake13634cf2000-06-29 19:17:04 +0000288 long 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) {
Fred Drake13634cf2000-06-29 19:17:04 +0000304 if (intpart > LONG_MAX || -intpart > LONG_MAX) {
Guido van Rossumf9fca921996-01-12 00:47:05 +0000305 /* 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 {
Fred Drake13634cf2000-06-29 19:17:04 +0000316 x = _Py_HashDouble(v->cval.real);
317 if (x == -1)
318 return -1;
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000319
320 if (v->cval.imag != 0.0) { /* Hash the imaginary part */
321 /* XXX Note that this hashes complex(x, y)
322 to the same value as complex(y, x).
323 Still better than it used to be :-) */
Fred Drake13634cf2000-06-29 19:17:04 +0000324 long y = _Py_HashDouble(v->cval.imag);
325 if (y == -1)
326 return -1;
327 x += y;
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000328 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000329 }
330 if (x == -1)
331 x = -2;
332 return x;
333}
334
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000335static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000336complex_add(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000337 PyComplexObject *v;
338 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000339{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000340 Py_complex result;
341 PyFPE_START_PROTECT("complex_add", return 0)
342 result = c_sum(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000343 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000344 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000345}
346
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000347static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000348complex_sub(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000349 PyComplexObject *v;
350 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000351{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000352 Py_complex result;
353 PyFPE_START_PROTECT("complex_sub", return 0)
354 result = c_diff(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000355 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000356 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000357}
358
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000359static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000360complex_mul(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000361 PyComplexObject *v;
362 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000363{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000364 Py_complex result;
365 PyFPE_START_PROTECT("complex_mul", return 0)
366 result = c_prod(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000367 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000368 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000369}
370
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000371static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000372complex_div(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000373 PyComplexObject *v;
374 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000375{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000376 Py_complex quot;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000377 PyFPE_START_PROTECT("complex_div", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000378 errno = 0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000379 quot = c_quot(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000380 PyFPE_END_PROTECT(quot)
Guido van Rossum96783941997-05-20 18:21:34 +0000381 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000382 PyErr_SetString(PyExc_ZeroDivisionError, "complex division");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000383 return NULL;
384 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000385 return PyComplex_FromCComplex(quot);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000386}
387
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000388static PyObject *
Guido van Rossumee09fc11996-09-11 13:55:55 +0000389complex_remainder(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000390 PyComplexObject *v;
391 PyComplexObject *w;
Guido van Rossumee09fc11996-09-11 13:55:55 +0000392{
Guido van Rossum3be12e91996-09-12 20:56:18 +0000393 Py_complex div, mod;
Guido van Rossum96783941997-05-20 18:21:34 +0000394 errno = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000395 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
Guido van Rossum96783941997-05-20 18:21:34 +0000396 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000397 PyErr_SetString(PyExc_ZeroDivisionError, "complex remainder");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000398 return NULL;
399 }
400 div.real = floor(div.real); /* Use the floor of the real part. */
401 div.imag = 0.0;
402 mod = c_diff(v->cval, c_prod(w->cval, div));
403
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000404 return PyComplex_FromCComplex(mod);
Guido van Rossumee09fc11996-09-11 13:55:55 +0000405}
406
Guido van Rossumee09fc11996-09-11 13:55:55 +0000407
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000408static PyObject *
Guido van Rossum3be12e91996-09-12 20:56:18 +0000409complex_divmod(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000410 PyComplexObject *v;
411 PyComplexObject *w;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000412{
413 Py_complex div, mod;
414 PyObject *d, *m, *z;
Guido van Rossum96783941997-05-20 18:21:34 +0000415 errno = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000416 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
Guido van Rossum96783941997-05-20 18:21:34 +0000417 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000418 PyErr_SetString(PyExc_ZeroDivisionError, "complex divmod()");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000419 return NULL;
420 }
421 div.real = floor(div.real); /* Use the floor of the real part. */
422 div.imag = 0.0;
423 mod = c_diff(v->cval, c_prod(w->cval, div));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000424 d = PyComplex_FromCComplex(div);
425 m = PyComplex_FromCComplex(mod);
426 z = Py_BuildValue("(OO)", d, m);
Guido van Rossum3be12e91996-09-12 20:56:18 +0000427 Py_XDECREF(d);
428 Py_XDECREF(m);
429 return z;
430}
Guido van Rossumf9fca921996-01-12 00:47:05 +0000431
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000432static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000433complex_pow(v, w, z)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000434 PyComplexObject *v;
435 PyObject *w;
436 PyComplexObject *z;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000437{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000438 Py_complex p;
439 Py_complex exponent;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000440 long int_exponent;
441
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000442 if ((PyObject *)z!=Py_None) {
443 PyErr_SetString(PyExc_ValueError, "complex modulo");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000444 return NULL;
445 }
446
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000447 PyFPE_START_PROTECT("complex_pow", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000448 errno = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000449 exponent = ((PyComplexObject*)w)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000450 int_exponent = (long)exponent.real;
451 if (exponent.imag == 0. && exponent.real == int_exponent)
452 p = c_powi(v->cval,int_exponent);
453 else
454 p = c_pow(v->cval,exponent);
455
Guido van Rossum45b83911997-03-14 04:32:50 +0000456 PyFPE_END_PROTECT(p)
Guido van Rossum96783941997-05-20 18:21:34 +0000457 if (errno == ERANGE) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000458 PyErr_SetString(PyExc_ValueError,
459 "0.0 to a negative or complex power");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000460 return NULL;
461 }
462
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000463 return PyComplex_FromCComplex(p);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000464}
465
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000466static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000467complex_neg(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000468 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000469{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000470 Py_complex neg;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000471 neg.real = -v->cval.real;
472 neg.imag = -v->cval.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000473 return PyComplex_FromCComplex(neg);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000474}
475
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000476static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000477complex_pos(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000478 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000479{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000480 Py_INCREF(v);
481 return (PyObject *)v;
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_abs(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000486 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000487{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000488 double result;
489 PyFPE_START_PROTECT("complex_abs", return 0)
490 result = hypot(v->cval.real,v->cval.imag);
Guido van Rossum45b83911997-03-14 04:32:50 +0000491 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000492 return PyFloat_FromDouble(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000493}
494
495static int
496complex_nonzero(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000497 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000498{
Guido van Rossum3bbef601999-01-25 19:42:19 +0000499 return v->cval.real != 0.0 || v->cval.imag != 0.0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000500}
501
502static int
503complex_coerce(pv, pw)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000504 PyObject **pv;
505 PyObject **pw;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000506{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000507 Py_complex cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000508 cval.imag = 0.;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000509 if (PyInt_Check(*pw)) {
510 cval.real = (double)PyInt_AsLong(*pw);
511 *pw = PyComplex_FromCComplex(cval);
512 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000513 return 0;
514 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000515 else if (PyLong_Check(*pw)) {
516 cval.real = PyLong_AsDouble(*pw);
517 *pw = PyComplex_FromCComplex(cval);
518 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000519 return 0;
520 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000521 else if (PyFloat_Check(*pw)) {
522 cval.real = PyFloat_AsDouble(*pw);
523 *pw = PyComplex_FromCComplex(cval);
524 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000525 return 0;
526 }
527 return 1; /* Can't do it */
528}
529
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000530static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000531complex_int(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000532 PyObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000533{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000534 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000535 "can't convert complex to int; use e.g. int(abs(z))");
536 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000537}
538
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000539static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000540complex_long(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000541 PyObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000542{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000543 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000544 "can't convert complex to long; use e.g. long(abs(z))");
545 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000546}
547
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000548static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000549complex_float(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 float; use e.g. 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 Rossum8530ef61998-05-07 16:29:10 +0000558complex_conjugate(self, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000559 PyObject *self;
Guido van Rossum8530ef61998-05-07 16:29:10 +0000560 PyObject *args;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000561{
Guido van Rossum926518b1996-08-19 19:30:45 +0000562 Py_complex c;
Guido van Rossum43713e52000-02-29 13:59:29 +0000563 if (!PyArg_ParseTuple(args, ":conjugate"))
Guido van Rossum8530ef61998-05-07 16:29:10 +0000564 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000565 c = ((PyComplexObject *)self)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000566 c.imag = -c.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000567 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000568}
569
570static PyMethodDef complex_methods[] = {
Guido van Rossum8530ef61998-05-07 16:29:10 +0000571 {"conjugate", complex_conjugate, 1},
Guido van Rossumf9fca921996-01-12 00:47:05 +0000572 {NULL, NULL} /* sentinel */
573};
574
575
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000576static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000577complex_getattr(self, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000578 PyComplexObject *self;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000579 char *name;
580{
Guido van Rossumf9fca921996-01-12 00:47:05 +0000581 if (strcmp(name, "real") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000582 return (PyObject *)PyFloat_FromDouble(self->cval.real);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000583 else if (strcmp(name, "imag") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000584 return (PyObject *)PyFloat_FromDouble(self->cval.imag);
Guido van Rossumc054d701997-04-01 03:12:33 +0000585 else if (strcmp(name, "__members__") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000586 return Py_BuildValue("[ss]", "imag", "real");
587 return Py_FindMethod(complex_methods, (PyObject *)self, name);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000588}
589
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000590static PyNumberMethods complex_as_number = {
Guido van Rossumf9fca921996-01-12 00:47:05 +0000591 (binaryfunc)complex_add, /*nb_add*/
592 (binaryfunc)complex_sub, /*nb_subtract*/
593 (binaryfunc)complex_mul, /*nb_multiply*/
594 (binaryfunc)complex_div, /*nb_divide*/
Guido van Rossumee09fc11996-09-11 13:55:55 +0000595 (binaryfunc)complex_remainder, /*nb_remainder*/
596 (binaryfunc)complex_divmod, /*nb_divmod*/
Guido van Rossumf9fca921996-01-12 00:47:05 +0000597 (ternaryfunc)complex_pow, /*nb_power*/
598 (unaryfunc)complex_neg, /*nb_negative*/
599 (unaryfunc)complex_pos, /*nb_positive*/
600 (unaryfunc)complex_abs, /*nb_absolute*/
601 (inquiry)complex_nonzero, /*nb_nonzero*/
602 0, /*nb_invert*/
603 0, /*nb_lshift*/
604 0, /*nb_rshift*/
605 0, /*nb_and*/
606 0, /*nb_xor*/
607 0, /*nb_or*/
608 (coercion)complex_coerce, /*nb_coerce*/
609 (unaryfunc)complex_int, /*nb_int*/
610 (unaryfunc)complex_long, /*nb_long*/
611 (unaryfunc)complex_float, /*nb_float*/
612 0, /*nb_oct*/
613 0, /*nb_hex*/
614};
615
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000616PyTypeObject PyComplex_Type = {
617 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000618 0,
619 "complex",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000620 sizeof(PyComplexObject),
Guido van Rossumf9fca921996-01-12 00:47:05 +0000621 0,
622 (destructor)complex_dealloc, /*tp_dealloc*/
623 (printfunc)complex_print, /*tp_print*/
624 (getattrfunc)complex_getattr, /*tp_getattr*/
625 0, /*tp_setattr*/
626 (cmpfunc)complex_compare, /*tp_compare*/
627 (reprfunc)complex_repr, /*tp_repr*/
628 &complex_as_number, /*tp_as_number*/
629 0, /*tp_as_sequence*/
630 0, /*tp_as_mapping*/
631 (hashfunc)complex_hash, /*tp_hash*/
632};
633
634#endif