blob: df8cf5a73cb7e5ae446a86b5f98ba22d4a6de4d3 [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
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007Copyright (c) 2000, BeOpen.com.
8Copyright (c) 1995-2000, Corporation for National Research Initiatives.
9Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
10All rights reserved.
Guido van Rossum96783941997-05-20 18:21:34 +000011
Guido van Rossumfd71b9e2000-06-30 23:50:40 +000012See the file "Misc/COPYRIGHT" for information on usage and
13redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum96783941997-05-20 18:21:34 +000014
15******************************************************************/
16
Guido van Rossumf9fca921996-01-12 00:47:05 +000017/* Complex object implementation */
18
19/* Borrows heavily from floatobject.c */
20
Guido van Rossum96783941997-05-20 18:21:34 +000021/* Submitted by Jim Hugunin */
22
Guido van Rossumf9fca921996-01-12 00:47:05 +000023#ifndef WITHOUT_COMPLEX
24
Guido van Rossumc0b618a1997-05-02 03:12:38 +000025#include "Python.h"
Guido van Rossumf9fca921996-01-12 00:47:05 +000026#include "mymath.h"
27
Guido van Rossumf9fca921996-01-12 00:47:05 +000028#ifdef HAVE_LIMITS_H
29#include <limits.h>
30#endif
31
Guido van Rossumf9fca921996-01-12 00:47:05 +000032
33/* elementary operations on complex numbers */
34
Guido van Rossum9e720e31996-07-21 02:31:35 +000035static Py_complex c_1 = {1., 0.};
Guido van Rossumf9fca921996-01-12 00:47:05 +000036
Guido van Rossum9e720e31996-07-21 02:31:35 +000037Py_complex c_sum(a,b)
38 Py_complex a,b;
Guido van Rossumf9fca921996-01-12 00:47:05 +000039{
Guido van Rossum9e720e31996-07-21 02:31:35 +000040 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000041 r.real = a.real + b.real;
42 r.imag = a.imag + b.imag;
43 return r;
44}
45
Guido van Rossum9e720e31996-07-21 02:31:35 +000046Py_complex c_diff(a,b)
47 Py_complex a,b;
Guido van Rossumf9fca921996-01-12 00:47:05 +000048{
Guido van Rossum9e720e31996-07-21 02:31:35 +000049 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000050 r.real = a.real - b.real;
51 r.imag = a.imag - b.imag;
52 return r;
53}
54
Guido van Rossum9e720e31996-07-21 02:31:35 +000055Py_complex c_neg(a)
56 Py_complex a;
Guido van Rossumf9fca921996-01-12 00:47:05 +000057{
Guido van Rossum9e720e31996-07-21 02:31:35 +000058 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000059 r.real = -a.real;
60 r.imag = -a.imag;
61 return r;
62}
63
Guido van Rossum9e720e31996-07-21 02:31:35 +000064Py_complex c_prod(a,b)
65 Py_complex a,b;
Guido van Rossumf9fca921996-01-12 00:47:05 +000066{
Guido van Rossum9e720e31996-07-21 02:31:35 +000067 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000068 r.real = a.real*b.real - a.imag*b.imag;
69 r.imag = a.real*b.imag + a.imag*b.real;
70 return r;
71}
72
Guido van Rossum9e720e31996-07-21 02:31:35 +000073Py_complex c_quot(a,b)
74 Py_complex a,b;
Guido van Rossumf9fca921996-01-12 00:47:05 +000075{
Guido van Rossum9e720e31996-07-21 02:31:35 +000076 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000077 double d = b.real*b.real + b.imag*b.imag;
78 if (d == 0.)
Guido van Rossum96783941997-05-20 18:21:34 +000079 errno = EDOM;
Guido van Rossumf9fca921996-01-12 00:47:05 +000080 r.real = (a.real*b.real + a.imag*b.imag)/d;
81 r.imag = (a.imag*b.real - a.real*b.imag)/d;
82 return r;
83}
84
Guido van Rossum9e720e31996-07-21 02:31:35 +000085Py_complex c_pow(a,b)
86 Py_complex a,b;
Guido van Rossumf9fca921996-01-12 00:47:05 +000087{
Guido van Rossum9e720e31996-07-21 02:31:35 +000088 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000089 double vabs,len,at,phase;
90 if (b.real == 0. && b.imag == 0.) {
91 r.real = 1.;
92 r.imag = 0.;
93 }
94 else if (a.real == 0. && a.imag == 0.) {
95 if (b.imag != 0. || b.real < 0.)
Guido van Rossum96783941997-05-20 18:21:34 +000096 errno = ERANGE;
Guido van Rossumf9fca921996-01-12 00:47:05 +000097 r.real = 0.;
98 r.imag = 0.;
99 }
100 else {
101 vabs = hypot(a.real,a.imag);
102 len = pow(vabs,b.real);
103 at = atan2(a.imag, a.real);
104 phase = at*b.real;
105 if (b.imag != 0.0) {
106 len /= exp(at*b.imag);
107 phase += b.imag*log(vabs);
108 }
109 r.real = len*cos(phase);
110 r.imag = len*sin(phase);
111 }
112 return r;
113}
114
Guido van Rossum9e720e31996-07-21 02:31:35 +0000115static Py_complex c_powu(x, n)
116 Py_complex x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000117 long n;
118{
Guido van Rossum926518b1996-08-19 19:30:45 +0000119 Py_complex r, p;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000120 long mask = 1;
Guido van Rossum926518b1996-08-19 19:30:45 +0000121 r = c_1;
122 p = x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000123 while (mask > 0 && n >= mask) {
124 if (n & mask)
125 r = c_prod(r,p);
126 mask <<= 1;
127 p = c_prod(p,p);
128 }
129 return r;
130}
131
Guido van Rossum9e720e31996-07-21 02:31:35 +0000132static Py_complex c_powi(x, n)
133 Py_complex x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000134 long n;
135{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000136 Py_complex cn;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000137
138 if (n > 100 || n < -100) {
139 cn.real = (double) n;
140 cn.imag = 0.;
141 return c_pow(x,cn);
142 }
143 else if (n > 0)
144 return c_powu(x,n);
145 else
146 return c_quot(c_1,c_powu(x,-n));
147
148}
149
150PyObject *
Guido van Rossum926518b1996-08-19 19:30:45 +0000151PyComplex_FromCComplex(cval)
152 Py_complex cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000153{
Guido van Rossumb18618d2000-05-03 23:44:39 +0000154 register PyComplexObject *op;
155
156 /* PyObject_New is inlined */
157 op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject));
Guido van Rossumf9fca921996-01-12 00:47:05 +0000158 if (op == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000159 return PyErr_NoMemory();
Guido van Rossumb18618d2000-05-03 23:44:39 +0000160 PyObject_INIT(op, &PyComplex_Type);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000161 op->cval = cval;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000162 return (PyObject *) op;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000163}
164
165PyObject *
Guido van Rossum926518b1996-08-19 19:30:45 +0000166PyComplex_FromDoubles(real, imag)
167 double real, imag;
168{
169 Py_complex c;
170 c.real = real;
171 c.imag = imag;
172 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000173}
174
175double
Guido van Rossum926518b1996-08-19 19:30:45 +0000176PyComplex_RealAsDouble(op)
177 PyObject *op;
178{
179 if (PyComplex_Check(op)) {
180 return ((PyComplexObject *)op)->cval.real;
181 } else {
182 return PyFloat_AsDouble(op);
183 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000184}
185
186double
Guido van Rossum926518b1996-08-19 19:30:45 +0000187PyComplex_ImagAsDouble(op)
188 PyObject *op;
189{
190 if (PyComplex_Check(op)) {
191 return ((PyComplexObject *)op)->cval.imag;
192 } else {
193 return 0.0;
194 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000195}
196
Guido van Rossum9e720e31996-07-21 02:31:35 +0000197Py_complex
Guido van Rossum926518b1996-08-19 19:30:45 +0000198PyComplex_AsCComplex(op)
199 PyObject *op;
200{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000201 Py_complex cv;
Guido van Rossumcf3d1081996-01-12 01:21:14 +0000202 if (PyComplex_Check(op)) {
203 return ((PyComplexObject *)op)->cval;
204 } else {
205 cv.real = PyFloat_AsDouble(op);
206 cv.imag = 0.;
207 return cv;
208 }
209}
210
Guido van Rossumf9fca921996-01-12 00:47:05 +0000211static void
212complex_dealloc(op)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000213 PyObject *op;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000214{
Guido van Rossumb18618d2000-05-03 23:44:39 +0000215 PyObject_DEL(op);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000216}
217
218
Guido van Rossum363078a1996-05-24 20:45:01 +0000219static void
Guido van Rossumf9fca921996-01-12 00:47:05 +0000220complex_buf_repr(buf, v)
221 char *buf;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000222 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000223{
224 if (v->cval.real == 0.)
Guido van Rossum72418791996-01-25 16:21:31 +0000225 sprintf(buf, "%.12gj", v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000226 else
Guido van Rossum72418791996-01-25 16:21:31 +0000227 sprintf(buf, "(%.12g%+.12gj)", v->cval.real, v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000228}
229
230static int
231complex_print(v, fp, flags)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000232 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000233 FILE *fp;
234 int flags; /* Not used but required by interface */
235{
236 char buf[100];
237 complex_buf_repr(buf, v);
238 fputs(buf, fp);
239 return 0;
240}
241
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000242static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000243complex_repr(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000244 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000245{
246 char buf[100];
247 complex_buf_repr(buf, v);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000248 return PyString_FromString(buf);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000249}
250
251static int
252complex_compare(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000253 PyComplexObject *v, *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000254{
255/* Note: "greater" and "smaller" have no meaning for complex numbers,
256 but Python requires that they be defined nevertheless. */
Guido van Rossum926518b1996-08-19 19:30:45 +0000257 Py_complex i, j;
258 i = v->cval;
259 j = w->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000260 if (i.real == j.real && i.imag == j.imag)
261 return 0;
262 else if (i.real != j.real)
263 return (i.real < j.real) ? -1 : 1;
264 else
265 return (i.imag < j.imag) ? -1 : 1;
266}
267
268static long
269complex_hash(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000270 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000271{
272 double intpart, fractpart;
Fred Drake13634cf2000-06-29 19:17:04 +0000273 long x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000274 /* This is designed so that Python numbers with the same
275 value hash to the same value, otherwise comparisons
276 of mapping keys will turn out weird */
277
278#ifdef MPW /* MPW C modf expects pointer to extended as second argument */
279{
280 extended e;
281 fractpart = modf(v->cval.real, &e);
282 intpart = e;
283}
284#else
285 fractpart = modf(v->cval.real, &intpart);
286#endif
287
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000288 if (fractpart == 0.0 && v->cval.imag == 0.0) {
Fred Drake13634cf2000-06-29 19:17:04 +0000289 if (intpart > LONG_MAX || -intpart > LONG_MAX) {
Guido van Rossumf9fca921996-01-12 00:47:05 +0000290 /* Convert to long int and use its hash... */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000291 PyObject *w = PyLong_FromDouble(v->cval.real);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000292 if (w == NULL)
293 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000294 x = PyObject_Hash(w);
295 Py_DECREF(w);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000296 return x;
297 }
298 x = (long)intpart;
299 }
300 else {
Fred Drake13634cf2000-06-29 19:17:04 +0000301 x = _Py_HashDouble(v->cval.real);
302 if (x == -1)
303 return -1;
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000304
305 if (v->cval.imag != 0.0) { /* Hash the imaginary part */
306 /* XXX Note that this hashes complex(x, y)
307 to the same value as complex(y, x).
308 Still better than it used to be :-) */
Fred Drake13634cf2000-06-29 19:17:04 +0000309 long y = _Py_HashDouble(v->cval.imag);
310 if (y == -1)
311 return -1;
312 x += y;
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000313 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000314 }
315 if (x == -1)
316 x = -2;
317 return x;
318}
319
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000320static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000321complex_add(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000322 PyComplexObject *v;
323 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000324{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000325 Py_complex result;
326 PyFPE_START_PROTECT("complex_add", return 0)
327 result = c_sum(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000328 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000329 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000330}
331
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000332static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000333complex_sub(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000334 PyComplexObject *v;
335 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000336{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000337 Py_complex result;
338 PyFPE_START_PROTECT("complex_sub", return 0)
339 result = c_diff(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000340 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000341 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000342}
343
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000344static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000345complex_mul(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000346 PyComplexObject *v;
347 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000348{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000349 Py_complex result;
350 PyFPE_START_PROTECT("complex_mul", return 0)
351 result = c_prod(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000352 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000353 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000354}
355
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000356static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000357complex_div(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000358 PyComplexObject *v;
359 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000360{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000361 Py_complex quot;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000362 PyFPE_START_PROTECT("complex_div", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000363 errno = 0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000364 quot = c_quot(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000365 PyFPE_END_PROTECT(quot)
Guido van Rossum96783941997-05-20 18:21:34 +0000366 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000367 PyErr_SetString(PyExc_ZeroDivisionError, "complex division");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000368 return NULL;
369 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000370 return PyComplex_FromCComplex(quot);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000371}
372
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000373static PyObject *
Guido van Rossumee09fc11996-09-11 13:55:55 +0000374complex_remainder(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000375 PyComplexObject *v;
376 PyComplexObject *w;
Guido van Rossumee09fc11996-09-11 13:55:55 +0000377{
Guido van Rossum3be12e91996-09-12 20:56:18 +0000378 Py_complex div, mod;
Guido van Rossum96783941997-05-20 18:21:34 +0000379 errno = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000380 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
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 remainder");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000383 return NULL;
384 }
385 div.real = floor(div.real); /* Use the floor of the real part. */
386 div.imag = 0.0;
387 mod = c_diff(v->cval, c_prod(w->cval, div));
388
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000389 return PyComplex_FromCComplex(mod);
Guido van Rossumee09fc11996-09-11 13:55:55 +0000390}
391
Guido van Rossumee09fc11996-09-11 13:55:55 +0000392
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000393static PyObject *
Guido van Rossum3be12e91996-09-12 20:56:18 +0000394complex_divmod(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000395 PyComplexObject *v;
396 PyComplexObject *w;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000397{
398 Py_complex div, mod;
399 PyObject *d, *m, *z;
Guido van Rossum96783941997-05-20 18:21:34 +0000400 errno = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000401 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
Guido van Rossum96783941997-05-20 18:21:34 +0000402 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000403 PyErr_SetString(PyExc_ZeroDivisionError, "complex divmod()");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000404 return NULL;
405 }
406 div.real = floor(div.real); /* Use the floor of the real part. */
407 div.imag = 0.0;
408 mod = c_diff(v->cval, c_prod(w->cval, div));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000409 d = PyComplex_FromCComplex(div);
410 m = PyComplex_FromCComplex(mod);
411 z = Py_BuildValue("(OO)", d, m);
Guido van Rossum3be12e91996-09-12 20:56:18 +0000412 Py_XDECREF(d);
413 Py_XDECREF(m);
414 return z;
415}
Guido van Rossumf9fca921996-01-12 00:47:05 +0000416
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000417static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000418complex_pow(v, w, z)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000419 PyComplexObject *v;
420 PyObject *w;
421 PyComplexObject *z;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000422{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000423 Py_complex p;
424 Py_complex exponent;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000425 long int_exponent;
426
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000427 if ((PyObject *)z!=Py_None) {
428 PyErr_SetString(PyExc_ValueError, "complex modulo");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000429 return NULL;
430 }
431
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000432 PyFPE_START_PROTECT("complex_pow", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000433 errno = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000434 exponent = ((PyComplexObject*)w)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000435 int_exponent = (long)exponent.real;
436 if (exponent.imag == 0. && exponent.real == int_exponent)
437 p = c_powi(v->cval,int_exponent);
438 else
439 p = c_pow(v->cval,exponent);
440
Guido van Rossum45b83911997-03-14 04:32:50 +0000441 PyFPE_END_PROTECT(p)
Guido van Rossum96783941997-05-20 18:21:34 +0000442 if (errno == ERANGE) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000443 PyErr_SetString(PyExc_ValueError,
444 "0.0 to a negative or complex power");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000445 return NULL;
446 }
447
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000448 return PyComplex_FromCComplex(p);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000449}
450
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000451static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000452complex_neg(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000453 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000454{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000455 Py_complex neg;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000456 neg.real = -v->cval.real;
457 neg.imag = -v->cval.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000458 return PyComplex_FromCComplex(neg);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000459}
460
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000461static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000462complex_pos(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000463 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000464{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000465 Py_INCREF(v);
466 return (PyObject *)v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000467}
468
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000469static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000470complex_abs(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000471 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000472{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000473 double result;
474 PyFPE_START_PROTECT("complex_abs", return 0)
475 result = hypot(v->cval.real,v->cval.imag);
Guido van Rossum45b83911997-03-14 04:32:50 +0000476 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000477 return PyFloat_FromDouble(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000478}
479
480static int
481complex_nonzero(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000482 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000483{
Guido van Rossum3bbef601999-01-25 19:42:19 +0000484 return v->cval.real != 0.0 || v->cval.imag != 0.0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000485}
486
487static int
488complex_coerce(pv, pw)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000489 PyObject **pv;
490 PyObject **pw;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000491{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000492 Py_complex cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000493 cval.imag = 0.;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000494 if (PyInt_Check(*pw)) {
495 cval.real = (double)PyInt_AsLong(*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 (PyLong_Check(*pw)) {
501 cval.real = PyLong_AsDouble(*pw);
502 *pw = PyComplex_FromCComplex(cval);
503 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000504 return 0;
505 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000506 else if (PyFloat_Check(*pw)) {
507 cval.real = PyFloat_AsDouble(*pw);
508 *pw = PyComplex_FromCComplex(cval);
509 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000510 return 0;
511 }
512 return 1; /* Can't do it */
513}
514
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000515static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000516complex_int(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000517 PyObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000518{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000519 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000520 "can't convert complex to int; use e.g. int(abs(z))");
521 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000522}
523
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000524static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000525complex_long(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000526 PyObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000527{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000528 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000529 "can't convert complex to long; use e.g. long(abs(z))");
530 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000531}
532
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000533static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000534complex_float(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000535 PyObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000536{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000537 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000538 "can't convert complex to float; use e.g. abs(z)");
539 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000540}
541
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000542static PyObject *
Guido van Rossum8530ef61998-05-07 16:29:10 +0000543complex_conjugate(self, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000544 PyObject *self;
Guido van Rossum8530ef61998-05-07 16:29:10 +0000545 PyObject *args;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000546{
Guido van Rossum926518b1996-08-19 19:30:45 +0000547 Py_complex c;
Guido van Rossum43713e52000-02-29 13:59:29 +0000548 if (!PyArg_ParseTuple(args, ":conjugate"))
Guido van Rossum8530ef61998-05-07 16:29:10 +0000549 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000550 c = ((PyComplexObject *)self)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000551 c.imag = -c.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000552 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000553}
554
555static PyMethodDef complex_methods[] = {
Guido van Rossum8530ef61998-05-07 16:29:10 +0000556 {"conjugate", complex_conjugate, 1},
Guido van Rossumf9fca921996-01-12 00:47:05 +0000557 {NULL, NULL} /* sentinel */
558};
559
560
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000561static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000562complex_getattr(self, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000563 PyComplexObject *self;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000564 char *name;
565{
Guido van Rossumf9fca921996-01-12 00:47:05 +0000566 if (strcmp(name, "real") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000567 return (PyObject *)PyFloat_FromDouble(self->cval.real);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000568 else if (strcmp(name, "imag") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000569 return (PyObject *)PyFloat_FromDouble(self->cval.imag);
Guido van Rossumc054d701997-04-01 03:12:33 +0000570 else if (strcmp(name, "__members__") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000571 return Py_BuildValue("[ss]", "imag", "real");
572 return Py_FindMethod(complex_methods, (PyObject *)self, name);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000573}
574
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000575static PyNumberMethods complex_as_number = {
Guido van Rossumf9fca921996-01-12 00:47:05 +0000576 (binaryfunc)complex_add, /*nb_add*/
577 (binaryfunc)complex_sub, /*nb_subtract*/
578 (binaryfunc)complex_mul, /*nb_multiply*/
579 (binaryfunc)complex_div, /*nb_divide*/
Guido van Rossumee09fc11996-09-11 13:55:55 +0000580 (binaryfunc)complex_remainder, /*nb_remainder*/
581 (binaryfunc)complex_divmod, /*nb_divmod*/
Guido van Rossumf9fca921996-01-12 00:47:05 +0000582 (ternaryfunc)complex_pow, /*nb_power*/
583 (unaryfunc)complex_neg, /*nb_negative*/
584 (unaryfunc)complex_pos, /*nb_positive*/
585 (unaryfunc)complex_abs, /*nb_absolute*/
586 (inquiry)complex_nonzero, /*nb_nonzero*/
587 0, /*nb_invert*/
588 0, /*nb_lshift*/
589 0, /*nb_rshift*/
590 0, /*nb_and*/
591 0, /*nb_xor*/
592 0, /*nb_or*/
593 (coercion)complex_coerce, /*nb_coerce*/
594 (unaryfunc)complex_int, /*nb_int*/
595 (unaryfunc)complex_long, /*nb_long*/
596 (unaryfunc)complex_float, /*nb_float*/
597 0, /*nb_oct*/
598 0, /*nb_hex*/
599};
600
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000601PyTypeObject PyComplex_Type = {
602 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000603 0,
604 "complex",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000605 sizeof(PyComplexObject),
Guido van Rossumf9fca921996-01-12 00:47:05 +0000606 0,
607 (destructor)complex_dealloc, /*tp_dealloc*/
608 (printfunc)complex_print, /*tp_print*/
609 (getattrfunc)complex_getattr, /*tp_getattr*/
610 0, /*tp_setattr*/
611 (cmpfunc)complex_compare, /*tp_compare*/
612 (reprfunc)complex_repr, /*tp_repr*/
613 &complex_as_number, /*tp_as_number*/
614 0, /*tp_as_sequence*/
615 0, /*tp_as_mapping*/
616 (hashfunc)complex_hash, /*tp_hash*/
617};
618
619#endif