blob: 7ef8a512681cf40c73c858226ee00ca04efb6524 [file] [log] [blame]
Guido van Rossum96783941997-05-20 18:21:34 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossum96783941997-05-20 18:21:34 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum96783941997-05-20 18:21:34 +00009******************************************************************/
10
Guido van Rossumf9fca921996-01-12 00:47:05 +000011/* Complex object implementation */
12
13/* Borrows heavily from floatobject.c */
14
Guido van Rossum96783941997-05-20 18:21:34 +000015/* Submitted by Jim Hugunin */
16
Guido van Rossumf9fca921996-01-12 00:47:05 +000017#ifndef WITHOUT_COMPLEX
18
Guido van Rossumc0b618a1997-05-02 03:12:38 +000019#include "Python.h"
Guido van Rossumf9fca921996-01-12 00:47:05 +000020#include "mymath.h"
21
Guido van Rossumf9fca921996-01-12 00:47:05 +000022#ifdef HAVE_LIMITS_H
23#include <limits.h>
24#endif
25
Guido van Rossumf9fca921996-01-12 00:47:05 +000026
27/* elementary operations on complex numbers */
28
Guido van Rossum9e720e31996-07-21 02:31:35 +000029static Py_complex c_1 = {1., 0.};
Guido van Rossumf9fca921996-01-12 00:47:05 +000030
Guido van Rossum9e720e31996-07-21 02:31:35 +000031Py_complex c_sum(a,b)
32 Py_complex a,b;
Guido van Rossumf9fca921996-01-12 00:47:05 +000033{
Guido van Rossum9e720e31996-07-21 02:31:35 +000034 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000035 r.real = a.real + b.real;
36 r.imag = a.imag + b.imag;
37 return r;
38}
39
Guido van Rossum9e720e31996-07-21 02:31:35 +000040Py_complex c_diff(a,b)
41 Py_complex a,b;
Guido van Rossumf9fca921996-01-12 00:47:05 +000042{
Guido van Rossum9e720e31996-07-21 02:31:35 +000043 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000044 r.real = a.real - b.real;
45 r.imag = a.imag - b.imag;
46 return r;
47}
48
Guido van Rossum9e720e31996-07-21 02:31:35 +000049Py_complex c_neg(a)
50 Py_complex a;
Guido van Rossumf9fca921996-01-12 00:47:05 +000051{
Guido van Rossum9e720e31996-07-21 02:31:35 +000052 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000053 r.real = -a.real;
54 r.imag = -a.imag;
55 return r;
56}
57
Guido van Rossum9e720e31996-07-21 02:31:35 +000058Py_complex c_prod(a,b)
59 Py_complex a,b;
Guido van Rossumf9fca921996-01-12 00:47:05 +000060{
Guido van Rossum9e720e31996-07-21 02:31:35 +000061 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000062 r.real = a.real*b.real - a.imag*b.imag;
63 r.imag = a.real*b.imag + a.imag*b.real;
64 return r;
65}
66
Guido van Rossum9e720e31996-07-21 02:31:35 +000067Py_complex c_quot(a,b)
68 Py_complex a,b;
Guido van Rossumf9fca921996-01-12 00:47:05 +000069{
Guido van Rossum9e720e31996-07-21 02:31:35 +000070 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000071 double d = b.real*b.real + b.imag*b.imag;
72 if (d == 0.)
Guido van Rossum96783941997-05-20 18:21:34 +000073 errno = EDOM;
Guido van Rossumf9fca921996-01-12 00:47:05 +000074 r.real = (a.real*b.real + a.imag*b.imag)/d;
75 r.imag = (a.imag*b.real - a.real*b.imag)/d;
76 return r;
77}
78
Guido van Rossum9e720e31996-07-21 02:31:35 +000079Py_complex c_pow(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 double vabs,len,at,phase;
84 if (b.real == 0. && b.imag == 0.) {
85 r.real = 1.;
86 r.imag = 0.;
87 }
88 else if (a.real == 0. && a.imag == 0.) {
89 if (b.imag != 0. || b.real < 0.)
Guido van Rossum96783941997-05-20 18:21:34 +000090 errno = ERANGE;
Guido van Rossumf9fca921996-01-12 00:47:05 +000091 r.real = 0.;
92 r.imag = 0.;
93 }
94 else {
95 vabs = hypot(a.real,a.imag);
96 len = pow(vabs,b.real);
97 at = atan2(a.imag, a.real);
98 phase = at*b.real;
99 if (b.imag != 0.0) {
100 len /= exp(at*b.imag);
101 phase += b.imag*log(vabs);
102 }
103 r.real = len*cos(phase);
104 r.imag = len*sin(phase);
105 }
106 return r;
107}
108
Guido van Rossum9e720e31996-07-21 02:31:35 +0000109static Py_complex c_powu(x, n)
110 Py_complex x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000111 long n;
112{
Guido van Rossum926518b1996-08-19 19:30:45 +0000113 Py_complex r, p;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000114 long mask = 1;
Guido van Rossum926518b1996-08-19 19:30:45 +0000115 r = c_1;
116 p = x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000117 while (mask > 0 && n >= mask) {
118 if (n & mask)
119 r = c_prod(r,p);
120 mask <<= 1;
121 p = c_prod(p,p);
122 }
123 return r;
124}
125
Guido van Rossum9e720e31996-07-21 02:31:35 +0000126static Py_complex c_powi(x, n)
127 Py_complex x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000128 long n;
129{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000130 Py_complex cn;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000131
132 if (n > 100 || n < -100) {
133 cn.real = (double) n;
134 cn.imag = 0.;
135 return c_pow(x,cn);
136 }
137 else if (n > 0)
138 return c_powu(x,n);
139 else
140 return c_quot(c_1,c_powu(x,-n));
141
142}
143
144PyObject *
Guido van Rossum926518b1996-08-19 19:30:45 +0000145PyComplex_FromCComplex(cval)
146 Py_complex cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000147{
Guido van Rossumb18618d2000-05-03 23:44:39 +0000148 register PyComplexObject *op;
149
150 /* PyObject_New is inlined */
151 op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject));
Guido van Rossumf9fca921996-01-12 00:47:05 +0000152 if (op == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000153 return PyErr_NoMemory();
Guido van Rossumb18618d2000-05-03 23:44:39 +0000154 PyObject_INIT(op, &PyComplex_Type);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000155 op->cval = cval;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000156 return (PyObject *) op;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000157}
158
159PyObject *
Guido van Rossum926518b1996-08-19 19:30:45 +0000160PyComplex_FromDoubles(real, imag)
161 double real, imag;
162{
163 Py_complex c;
164 c.real = real;
165 c.imag = imag;
166 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000167}
168
169double
Guido van Rossum926518b1996-08-19 19:30:45 +0000170PyComplex_RealAsDouble(op)
171 PyObject *op;
172{
173 if (PyComplex_Check(op)) {
174 return ((PyComplexObject *)op)->cval.real;
175 } else {
176 return PyFloat_AsDouble(op);
177 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000178}
179
180double
Guido van Rossum926518b1996-08-19 19:30:45 +0000181PyComplex_ImagAsDouble(op)
182 PyObject *op;
183{
184 if (PyComplex_Check(op)) {
185 return ((PyComplexObject *)op)->cval.imag;
186 } else {
187 return 0.0;
188 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000189}
190
Guido van Rossum9e720e31996-07-21 02:31:35 +0000191Py_complex
Guido van Rossum926518b1996-08-19 19:30:45 +0000192PyComplex_AsCComplex(op)
193 PyObject *op;
194{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000195 Py_complex cv;
Guido van Rossumcf3d1081996-01-12 01:21:14 +0000196 if (PyComplex_Check(op)) {
197 return ((PyComplexObject *)op)->cval;
198 } else {
199 cv.real = PyFloat_AsDouble(op);
200 cv.imag = 0.;
201 return cv;
202 }
203}
204
Guido van Rossumf9fca921996-01-12 00:47:05 +0000205static void
206complex_dealloc(op)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000207 PyObject *op;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000208{
Guido van Rossumb18618d2000-05-03 23:44:39 +0000209 PyObject_DEL(op);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000210}
211
212
Guido van Rossum363078a1996-05-24 20:45:01 +0000213static void
Guido van Rossumf9fca921996-01-12 00:47:05 +0000214complex_buf_repr(buf, v)
215 char *buf;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000216 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000217{
218 if (v->cval.real == 0.)
Guido van Rossum72418791996-01-25 16:21:31 +0000219 sprintf(buf, "%.12gj", v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000220 else
Guido van Rossum72418791996-01-25 16:21:31 +0000221 sprintf(buf, "(%.12g%+.12gj)", v->cval.real, v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000222}
223
224static int
225complex_print(v, fp, flags)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000226 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000227 FILE *fp;
228 int flags; /* Not used but required by interface */
229{
230 char buf[100];
231 complex_buf_repr(buf, v);
232 fputs(buf, fp);
233 return 0;
234}
235
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000236static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000237complex_repr(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000238 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000239{
240 char buf[100];
241 complex_buf_repr(buf, v);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000242 return PyString_FromString(buf);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000243}
244
245static int
246complex_compare(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000247 PyComplexObject *v, *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000248{
249/* Note: "greater" and "smaller" have no meaning for complex numbers,
250 but Python requires that they be defined nevertheless. */
Guido van Rossum926518b1996-08-19 19:30:45 +0000251 Py_complex i, j;
252 i = v->cval;
253 j = w->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000254 if (i.real == j.real && i.imag == j.imag)
255 return 0;
256 else if (i.real != j.real)
257 return (i.real < j.real) ? -1 : 1;
258 else
259 return (i.imag < j.imag) ? -1 : 1;
260}
261
262static long
263complex_hash(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000264 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000265{
266 double intpart, fractpart;
Fred Drake13634cf2000-06-29 19:17:04 +0000267 long x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000268 /* This is designed so that Python numbers with the same
269 value hash to the same value, otherwise comparisons
270 of mapping keys will turn out weird */
271
272#ifdef MPW /* MPW C modf expects pointer to extended as second argument */
273{
274 extended e;
275 fractpart = modf(v->cval.real, &e);
276 intpart = e;
277}
278#else
279 fractpart = modf(v->cval.real, &intpart);
280#endif
281
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000282 if (fractpart == 0.0 && v->cval.imag == 0.0) {
Fred Drake13634cf2000-06-29 19:17:04 +0000283 if (intpart > LONG_MAX || -intpart > LONG_MAX) {
Guido van Rossumf9fca921996-01-12 00:47:05 +0000284 /* Convert to long int and use its hash... */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000285 PyObject *w = PyLong_FromDouble(v->cval.real);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000286 if (w == NULL)
287 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000288 x = PyObject_Hash(w);
289 Py_DECREF(w);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000290 return x;
291 }
292 x = (long)intpart;
293 }
294 else {
Fred Drake13634cf2000-06-29 19:17:04 +0000295 x = _Py_HashDouble(v->cval.real);
296 if (x == -1)
297 return -1;
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000298
299 if (v->cval.imag != 0.0) { /* Hash the imaginary part */
300 /* XXX Note that this hashes complex(x, y)
301 to the same value as complex(y, x).
302 Still better than it used to be :-) */
Fred Drake13634cf2000-06-29 19:17:04 +0000303 long y = _Py_HashDouble(v->cval.imag);
304 if (y == -1)
305 return -1;
306 x += y;
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000307 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000308 }
309 if (x == -1)
310 x = -2;
311 return x;
312}
313
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000314static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000315complex_add(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000316 PyComplexObject *v;
317 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000318{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000319 Py_complex result;
320 PyFPE_START_PROTECT("complex_add", return 0)
321 result = c_sum(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000322 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000323 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000324}
325
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000326static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000327complex_sub(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000328 PyComplexObject *v;
329 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000330{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000331 Py_complex result;
332 PyFPE_START_PROTECT("complex_sub", return 0)
333 result = c_diff(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000334 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000335 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000336}
337
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000338static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000339complex_mul(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000340 PyComplexObject *v;
341 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000342{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000343 Py_complex result;
344 PyFPE_START_PROTECT("complex_mul", return 0)
345 result = c_prod(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000346 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000347 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000348}
349
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000350static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000351complex_div(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000352 PyComplexObject *v;
353 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000354{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000355 Py_complex quot;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000356 PyFPE_START_PROTECT("complex_div", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000357 errno = 0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000358 quot = c_quot(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000359 PyFPE_END_PROTECT(quot)
Guido van Rossum96783941997-05-20 18:21:34 +0000360 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000361 PyErr_SetString(PyExc_ZeroDivisionError, "complex division");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000362 return NULL;
363 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000364 return PyComplex_FromCComplex(quot);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000365}
366
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000367static PyObject *
Guido van Rossumee09fc11996-09-11 13:55:55 +0000368complex_remainder(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000369 PyComplexObject *v;
370 PyComplexObject *w;
Guido van Rossumee09fc11996-09-11 13:55:55 +0000371{
Guido van Rossum3be12e91996-09-12 20:56:18 +0000372 Py_complex div, mod;
Guido van Rossum96783941997-05-20 18:21:34 +0000373 errno = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000374 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
Guido van Rossum96783941997-05-20 18:21:34 +0000375 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000376 PyErr_SetString(PyExc_ZeroDivisionError, "complex remainder");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000377 return NULL;
378 }
379 div.real = floor(div.real); /* Use the floor of the real part. */
380 div.imag = 0.0;
381 mod = c_diff(v->cval, c_prod(w->cval, div));
382
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000383 return PyComplex_FromCComplex(mod);
Guido van Rossumee09fc11996-09-11 13:55:55 +0000384}
385
Guido van Rossumee09fc11996-09-11 13:55:55 +0000386
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000387static PyObject *
Guido van Rossum3be12e91996-09-12 20:56:18 +0000388complex_divmod(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000389 PyComplexObject *v;
390 PyComplexObject *w;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000391{
392 Py_complex div, mod;
393 PyObject *d, *m, *z;
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 divmod()");
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));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000403 d = PyComplex_FromCComplex(div);
404 m = PyComplex_FromCComplex(mod);
405 z = Py_BuildValue("(OO)", d, m);
Guido van Rossum3be12e91996-09-12 20:56:18 +0000406 Py_XDECREF(d);
407 Py_XDECREF(m);
408 return z;
409}
Guido van Rossumf9fca921996-01-12 00:47:05 +0000410
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000411static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000412complex_pow(v, w, z)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000413 PyComplexObject *v;
414 PyObject *w;
415 PyComplexObject *z;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000416{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000417 Py_complex p;
418 Py_complex exponent;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000419 long int_exponent;
420
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000421 if ((PyObject *)z!=Py_None) {
422 PyErr_SetString(PyExc_ValueError, "complex modulo");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000423 return NULL;
424 }
425
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000426 PyFPE_START_PROTECT("complex_pow", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000427 errno = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000428 exponent = ((PyComplexObject*)w)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000429 int_exponent = (long)exponent.real;
430 if (exponent.imag == 0. && exponent.real == int_exponent)
431 p = c_powi(v->cval,int_exponent);
432 else
433 p = c_pow(v->cval,exponent);
434
Guido van Rossum45b83911997-03-14 04:32:50 +0000435 PyFPE_END_PROTECT(p)
Guido van Rossum96783941997-05-20 18:21:34 +0000436 if (errno == ERANGE) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000437 PyErr_SetString(PyExc_ValueError,
438 "0.0 to a negative or complex power");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000439 return NULL;
440 }
441
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000442 return PyComplex_FromCComplex(p);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000443}
444
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000445static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000446complex_neg(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000447 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000448{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000449 Py_complex neg;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000450 neg.real = -v->cval.real;
451 neg.imag = -v->cval.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000452 return PyComplex_FromCComplex(neg);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000453}
454
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000455static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000456complex_pos(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000457 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000458{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000459 Py_INCREF(v);
460 return (PyObject *)v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000461}
462
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000463static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000464complex_abs(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000465 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000466{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000467 double result;
468 PyFPE_START_PROTECT("complex_abs", return 0)
469 result = hypot(v->cval.real,v->cval.imag);
Guido van Rossum45b83911997-03-14 04:32:50 +0000470 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000471 return PyFloat_FromDouble(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000472}
473
474static int
475complex_nonzero(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000476 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000477{
Guido van Rossum3bbef601999-01-25 19:42:19 +0000478 return v->cval.real != 0.0 || v->cval.imag != 0.0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000479}
480
481static int
482complex_coerce(pv, pw)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000483 PyObject **pv;
484 PyObject **pw;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000485{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000486 Py_complex cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000487 cval.imag = 0.;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000488 if (PyInt_Check(*pw)) {
489 cval.real = (double)PyInt_AsLong(*pw);
490 *pw = PyComplex_FromCComplex(cval);
491 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000492 return 0;
493 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000494 else if (PyLong_Check(*pw)) {
495 cval.real = PyLong_AsDouble(*pw);
496 *pw = PyComplex_FromCComplex(cval);
497 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000498 return 0;
499 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000500 else if (PyFloat_Check(*pw)) {
501 cval.real = PyFloat_AsDouble(*pw);
502 *pw = PyComplex_FromCComplex(cval);
503 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000504 return 0;
505 }
506 return 1; /* Can't do it */
507}
508
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000509static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000510complex_int(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000511 PyObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000512{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000513 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000514 "can't convert complex to int; use e.g. int(abs(z))");
515 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000516}
517
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000518static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000519complex_long(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000520 PyObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000521{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000522 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000523 "can't convert complex to long; use e.g. long(abs(z))");
524 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000525}
526
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000527static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000528complex_float(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000529 PyObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000530{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000531 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000532 "can't convert complex to float; use e.g. abs(z)");
533 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000534}
535
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000536static PyObject *
Guido van Rossum8530ef61998-05-07 16:29:10 +0000537complex_conjugate(self, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000538 PyObject *self;
Guido van Rossum8530ef61998-05-07 16:29:10 +0000539 PyObject *args;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000540{
Guido van Rossum926518b1996-08-19 19:30:45 +0000541 Py_complex c;
Guido van Rossum43713e52000-02-29 13:59:29 +0000542 if (!PyArg_ParseTuple(args, ":conjugate"))
Guido van Rossum8530ef61998-05-07 16:29:10 +0000543 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000544 c = ((PyComplexObject *)self)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000545 c.imag = -c.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000546 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000547}
548
549static PyMethodDef complex_methods[] = {
Guido van Rossum8530ef61998-05-07 16:29:10 +0000550 {"conjugate", complex_conjugate, 1},
Guido van Rossumf9fca921996-01-12 00:47:05 +0000551 {NULL, NULL} /* sentinel */
552};
553
554
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000555static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000556complex_getattr(self, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000557 PyComplexObject *self;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000558 char *name;
559{
Guido van Rossumf9fca921996-01-12 00:47:05 +0000560 if (strcmp(name, "real") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000561 return (PyObject *)PyFloat_FromDouble(self->cval.real);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000562 else if (strcmp(name, "imag") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000563 return (PyObject *)PyFloat_FromDouble(self->cval.imag);
Guido van Rossumc054d701997-04-01 03:12:33 +0000564 else if (strcmp(name, "__members__") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000565 return Py_BuildValue("[ss]", "imag", "real");
566 return Py_FindMethod(complex_methods, (PyObject *)self, name);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000567}
568
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000569static PyNumberMethods complex_as_number = {
Guido van Rossumf9fca921996-01-12 00:47:05 +0000570 (binaryfunc)complex_add, /*nb_add*/
571 (binaryfunc)complex_sub, /*nb_subtract*/
572 (binaryfunc)complex_mul, /*nb_multiply*/
573 (binaryfunc)complex_div, /*nb_divide*/
Guido van Rossumee09fc11996-09-11 13:55:55 +0000574 (binaryfunc)complex_remainder, /*nb_remainder*/
575 (binaryfunc)complex_divmod, /*nb_divmod*/
Guido van Rossumf9fca921996-01-12 00:47:05 +0000576 (ternaryfunc)complex_pow, /*nb_power*/
577 (unaryfunc)complex_neg, /*nb_negative*/
578 (unaryfunc)complex_pos, /*nb_positive*/
579 (unaryfunc)complex_abs, /*nb_absolute*/
580 (inquiry)complex_nonzero, /*nb_nonzero*/
581 0, /*nb_invert*/
582 0, /*nb_lshift*/
583 0, /*nb_rshift*/
584 0, /*nb_and*/
585 0, /*nb_xor*/
586 0, /*nb_or*/
587 (coercion)complex_coerce, /*nb_coerce*/
588 (unaryfunc)complex_int, /*nb_int*/
589 (unaryfunc)complex_long, /*nb_long*/
590 (unaryfunc)complex_float, /*nb_float*/
591 0, /*nb_oct*/
592 0, /*nb_hex*/
593};
594
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000595PyTypeObject PyComplex_Type = {
596 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000597 0,
598 "complex",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000599 sizeof(PyComplexObject),
Guido van Rossumf9fca921996-01-12 00:47:05 +0000600 0,
601 (destructor)complex_dealloc, /*tp_dealloc*/
602 (printfunc)complex_print, /*tp_print*/
603 (getattrfunc)complex_getattr, /*tp_getattr*/
604 0, /*tp_setattr*/
605 (cmpfunc)complex_compare, /*tp_compare*/
606 (reprfunc)complex_repr, /*tp_repr*/
607 &complex_as_number, /*tp_as_number*/
608 0, /*tp_as_sequence*/
609 0, /*tp_as_mapping*/
610 (hashfunc)complex_hash, /*tp_hash*/
611};
612
613#endif