blob: 0ad665d029f83f0887fc1b992406a4cb3dd6294d [file] [log] [blame]
Guido van Rossumf9fca921996-01-12 00:47:05 +00001/* Complex object implementation */
2
3/* Borrows heavily from floatobject.c */
4
5#ifndef WITHOUT_COMPLEX
6
Guido van Rossumc0b618a1997-05-02 03:12:38 +00007#include "Python.h"
Guido van Rossumf9fca921996-01-12 00:47:05 +00008#include "mymath.h"
9
10#ifdef i860
11/* Cray APP has bogus definition of HUGE_VAL in <math.h> */
12#undef HUGE_VAL
13#endif
14
15#ifdef HUGE_VAL
16#define CHECK(x) if (errno != 0) ; \
17 else if (-HUGE_VAL <= (x) && (x) <= HUGE_VAL) ; \
18 else errno = ERANGE
19#else
20#define CHECK(x) /* Don't know how to check */
21#endif
22
23#ifdef HAVE_LIMITS_H
24#include <limits.h>
25#endif
26
27#ifndef LONG_MAX
28#define LONG_MAX 0X7FFFFFFFL
29#endif
30
31#ifndef LONG_MIN
32#define LONG_MIN (-LONG_MAX-1)
33#endif
34
35#ifdef __NeXT__
36#ifdef __sparc__
37/*
38 * This works around a bug in the NS/Sparc 3.3 pre-release
39 * limits.h header file.
40 * 10-Feb-1995 bwarsaw@cnri.reston.va.us
41 */
42#undef LONG_MIN
43#define LONG_MIN (-LONG_MAX-1)
44#endif
45#endif
46
47#if !defined(__STDC__) && !defined(macintosh)
Guido van Rossumc0b618a1997-05-02 03:12:38 +000048extern double fmod Py_PROTO((double, double));
49extern double pow Py_PROTO((double, double));
Guido van Rossumf9fca921996-01-12 00:47:05 +000050#endif
51
52
53/* elementary operations on complex numbers */
54
Guido van Rossum363078a1996-05-24 20:45:01 +000055static int c_error;
Guido van Rossum9e720e31996-07-21 02:31:35 +000056static Py_complex c_1 = {1., 0.};
Guido van Rossumf9fca921996-01-12 00:47:05 +000057
Guido van Rossum9e720e31996-07-21 02:31:35 +000058Py_complex c_sum(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;
63 r.imag = a.imag + b.imag;
64 return r;
65}
66
Guido van Rossum9e720e31996-07-21 02:31:35 +000067Py_complex c_diff(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 r.real = a.real - b.real;
72 r.imag = a.imag - b.imag;
73 return r;
74}
75
Guido van Rossum9e720e31996-07-21 02:31:35 +000076Py_complex c_neg(a)
77 Py_complex a;
Guido van Rossumf9fca921996-01-12 00:47:05 +000078{
Guido van Rossum9e720e31996-07-21 02:31:35 +000079 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000080 r.real = -a.real;
81 r.imag = -a.imag;
82 return r;
83}
84
Guido van Rossum9e720e31996-07-21 02:31:35 +000085Py_complex c_prod(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 r.real = a.real*b.real - a.imag*b.imag;
90 r.imag = a.real*b.imag + a.imag*b.real;
91 return r;
92}
93
Guido van Rossum9e720e31996-07-21 02:31:35 +000094Py_complex c_quot(a,b)
95 Py_complex a,b;
Guido van Rossumf9fca921996-01-12 00:47:05 +000096{
Guido van Rossum9e720e31996-07-21 02:31:35 +000097 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000098 double d = b.real*b.real + b.imag*b.imag;
99 if (d == 0.)
100 c_error = 1;
101 r.real = (a.real*b.real + a.imag*b.imag)/d;
102 r.imag = (a.imag*b.real - a.real*b.imag)/d;
103 return r;
104}
105
Guido van Rossum9e720e31996-07-21 02:31:35 +0000106Py_complex c_pow(a,b)
107 Py_complex a,b;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000108{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000109 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000110 double vabs,len,at,phase;
111 if (b.real == 0. && b.imag == 0.) {
112 r.real = 1.;
113 r.imag = 0.;
114 }
115 else if (a.real == 0. && a.imag == 0.) {
116 if (b.imag != 0. || b.real < 0.)
117 c_error = 2;
118 r.real = 0.;
119 r.imag = 0.;
120 }
121 else {
122 vabs = hypot(a.real,a.imag);
123 len = pow(vabs,b.real);
124 at = atan2(a.imag, a.real);
125 phase = at*b.real;
126 if (b.imag != 0.0) {
127 len /= exp(at*b.imag);
128 phase += b.imag*log(vabs);
129 }
130 r.real = len*cos(phase);
131 r.imag = len*sin(phase);
132 }
133 return r;
134}
135
Guido van Rossum9e720e31996-07-21 02:31:35 +0000136static Py_complex c_powu(x, n)
137 Py_complex x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000138 long n;
139{
Guido van Rossum926518b1996-08-19 19:30:45 +0000140 Py_complex r, p;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000141 long mask = 1;
Guido van Rossum926518b1996-08-19 19:30:45 +0000142 r = c_1;
143 p = x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000144 while (mask > 0 && n >= mask) {
145 if (n & mask)
146 r = c_prod(r,p);
147 mask <<= 1;
148 p = c_prod(p,p);
149 }
150 return r;
151}
152
Guido van Rossum9e720e31996-07-21 02:31:35 +0000153static Py_complex c_powi(x, n)
154 Py_complex x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000155 long n;
156{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000157 Py_complex cn;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000158
159 if (n > 100 || n < -100) {
160 cn.real = (double) n;
161 cn.imag = 0.;
162 return c_pow(x,cn);
163 }
164 else if (n > 0)
165 return c_powu(x,n);
166 else
167 return c_quot(c_1,c_powu(x,-n));
168
169}
170
171PyObject *
Guido van Rossum926518b1996-08-19 19:30:45 +0000172PyComplex_FromCComplex(cval)
173 Py_complex cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000174{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000175 register PyComplexObject *op =
176 (PyComplexObject *) malloc(sizeof(PyComplexObject));
Guido van Rossumf9fca921996-01-12 00:47:05 +0000177 if (op == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000178 return PyErr_NoMemory();
179 op->ob_type = &PyComplex_Type;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000180 op->cval = cval;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000181 _Py_NewReference(op);
182 return (PyObject *) op;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000183}
184
185PyObject *
Guido van Rossum926518b1996-08-19 19:30:45 +0000186PyComplex_FromDoubles(real, imag)
187 double real, imag;
188{
189 Py_complex c;
190 c.real = real;
191 c.imag = imag;
192 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000193}
194
195double
Guido van Rossum926518b1996-08-19 19:30:45 +0000196PyComplex_RealAsDouble(op)
197 PyObject *op;
198{
199 if (PyComplex_Check(op)) {
200 return ((PyComplexObject *)op)->cval.real;
201 } else {
202 return PyFloat_AsDouble(op);
203 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000204}
205
206double
Guido van Rossum926518b1996-08-19 19:30:45 +0000207PyComplex_ImagAsDouble(op)
208 PyObject *op;
209{
210 if (PyComplex_Check(op)) {
211 return ((PyComplexObject *)op)->cval.imag;
212 } else {
213 return 0.0;
214 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000215}
216
Guido van Rossum9e720e31996-07-21 02:31:35 +0000217Py_complex
Guido van Rossum926518b1996-08-19 19:30:45 +0000218PyComplex_AsCComplex(op)
219 PyObject *op;
220{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000221 Py_complex cv;
Guido van Rossumcf3d1081996-01-12 01:21:14 +0000222 if (PyComplex_Check(op)) {
223 return ((PyComplexObject *)op)->cval;
224 } else {
225 cv.real = PyFloat_AsDouble(op);
226 cv.imag = 0.;
227 return cv;
228 }
229}
230
Guido van Rossumf9fca921996-01-12 00:47:05 +0000231static void
232complex_dealloc(op)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000233 PyObject *op;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000234{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000235 PyMem_DEL(op);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000236}
237
238
Guido van Rossum363078a1996-05-24 20:45:01 +0000239static void
Guido van Rossumf9fca921996-01-12 00:47:05 +0000240complex_buf_repr(buf, v)
241 char *buf;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000242 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000243{
244 if (v->cval.real == 0.)
Guido van Rossum72418791996-01-25 16:21:31 +0000245 sprintf(buf, "%.12gj", v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000246 else
Guido van Rossum72418791996-01-25 16:21:31 +0000247 sprintf(buf, "(%.12g%+.12gj)", v->cval.real, v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000248}
249
250static int
251complex_print(v, fp, flags)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000252 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000253 FILE *fp;
254 int flags; /* Not used but required by interface */
255{
256 char buf[100];
257 complex_buf_repr(buf, v);
258 fputs(buf, fp);
259 return 0;
260}
261
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000262static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000263complex_repr(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000264 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000265{
266 char buf[100];
267 complex_buf_repr(buf, v);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000268 return PyString_FromString(buf);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000269}
270
271static int
272complex_compare(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000273 PyComplexObject *v, *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000274{
275/* Note: "greater" and "smaller" have no meaning for complex numbers,
276 but Python requires that they be defined nevertheless. */
Guido van Rossum926518b1996-08-19 19:30:45 +0000277 Py_complex i, j;
278 i = v->cval;
279 j = w->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000280 if (i.real == j.real && i.imag == j.imag)
281 return 0;
282 else if (i.real != j.real)
283 return (i.real < j.real) ? -1 : 1;
284 else
285 return (i.imag < j.imag) ? -1 : 1;
286}
287
288static long
289complex_hash(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000290 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000291{
292 double intpart, fractpart;
293 int expo;
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000294 long hipart, x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000295 /* This is designed so that Python numbers with the same
296 value hash to the same value, otherwise comparisons
297 of mapping keys will turn out weird */
298
299#ifdef MPW /* MPW C modf expects pointer to extended as second argument */
300{
301 extended e;
302 fractpart = modf(v->cval.real, &e);
303 intpart = e;
304}
305#else
306 fractpart = modf(v->cval.real, &intpart);
307#endif
308
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000309 if (fractpart == 0.0 && v->cval.imag == 0.0) {
Guido van Rossumf9fca921996-01-12 00:47:05 +0000310 if (intpart > 0x7fffffffL || -intpart > 0x7fffffffL) {
311 /* Convert to long int and use its hash... */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000312 PyObject *w = PyLong_FromDouble(v->cval.real);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000313 if (w == NULL)
314 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000315 x = PyObject_Hash(w);
316 Py_DECREF(w);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000317 return x;
318 }
319 x = (long)intpart;
320 }
321 else {
322 fractpart = frexp(fractpart, &expo);
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000323 fractpart = fractpart * 2147483648.0; /* 2**31 */
324 hipart = (long)fractpart; /* Take the top 32 bits */
325 fractpart = (fractpart - (double)hipart) * 2147483648.0;
326 /* Get the next 32 bits */
327 x = hipart + (long)fractpart + (long)intpart + (expo << 15);
328 /* Combine everything */
329
330 if (v->cval.imag != 0.0) { /* Hash the imaginary part */
331 /* XXX Note that this hashes complex(x, y)
332 to the same value as complex(y, x).
333 Still better than it used to be :-) */
334#ifdef MPW
335 {
336 extended e;
337 fractpart = modf(v->cval.imag, &e);
338 intpart = e;
339 }
340#else
341 fractpart = modf(v->cval.imag, &intpart);
342#endif
343 fractpart = frexp(fractpart, &expo);
344 fractpart = fractpart * 2147483648.0; /* 2**31 */
345 hipart = (long)fractpart; /* Take the top 32 bits */
346 fractpart =
347 (fractpart - (double)hipart) * 2147483648.0;
348 /* Get the next 32 bits */
349 x ^= hipart + (long)fractpart +
350 (long)intpart + (expo << 15);
351 /* Combine everything */
352 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000353 }
354 if (x == -1)
355 x = -2;
356 return x;
357}
358
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000359static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000360complex_add(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_add", return 0)
366 result = c_sum(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_sub(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 Rossum09e6ad01997-02-14 22:54:21 +0000376 Py_complex result;
377 PyFPE_START_PROTECT("complex_sub", return 0)
378 result = c_diff(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000379 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000380 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000381}
382
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000383static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000384complex_mul(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000385 PyComplexObject *v;
386 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000387{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000388 Py_complex result;
389 PyFPE_START_PROTECT("complex_mul", return 0)
390 result = c_prod(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000391 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000392 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000393}
394
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000395static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000396complex_div(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000397 PyComplexObject *v;
398 PyComplexObject *w;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000399{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000400 Py_complex quot;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000401 PyFPE_START_PROTECT("complex_div", return 0)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000402 c_error = 0;
403 quot = c_quot(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000404 PyFPE_END_PROTECT(quot)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000405 if (c_error == 1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000406 PyErr_SetString(PyExc_ZeroDivisionError, "complex division");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000407 return NULL;
408 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000409 return PyComplex_FromCComplex(quot);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000410}
411
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000412static PyObject *
Guido van Rossumee09fc11996-09-11 13:55:55 +0000413complex_remainder(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000414 PyComplexObject *v;
415 PyComplexObject *w;
Guido van Rossumee09fc11996-09-11 13:55:55 +0000416{
Guido van Rossum3be12e91996-09-12 20:56:18 +0000417 Py_complex div, mod;
Guido van Rossum24048581996-09-12 21:02:02 +0000418 c_error = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000419 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
420 if (c_error == 1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000421 PyErr_SetString(PyExc_ZeroDivisionError, "complex remainder");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000422 return NULL;
423 }
424 div.real = floor(div.real); /* Use the floor of the real part. */
425 div.imag = 0.0;
426 mod = c_diff(v->cval, c_prod(w->cval, div));
427
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000428 return PyComplex_FromCComplex(mod);
Guido van Rossumee09fc11996-09-11 13:55:55 +0000429}
430
Guido van Rossumee09fc11996-09-11 13:55:55 +0000431
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000432static PyObject *
Guido van Rossum3be12e91996-09-12 20:56:18 +0000433complex_divmod(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000434 PyComplexObject *v;
435 PyComplexObject *w;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000436{
437 Py_complex div, mod;
438 PyObject *d, *m, *z;
Guido van Rossum24048581996-09-12 21:02:02 +0000439 c_error = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000440 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
441 if (c_error == 1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000442 PyErr_SetString(PyExc_ZeroDivisionError, "complex divmod()");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000443 return NULL;
444 }
445 div.real = floor(div.real); /* Use the floor of the real part. */
446 div.imag = 0.0;
447 mod = c_diff(v->cval, c_prod(w->cval, div));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000448 d = PyComplex_FromCComplex(div);
449 m = PyComplex_FromCComplex(mod);
450 z = Py_BuildValue("(OO)", d, m);
Guido van Rossum3be12e91996-09-12 20:56:18 +0000451 Py_XDECREF(d);
452 Py_XDECREF(m);
453 return z;
454}
Guido van Rossumf9fca921996-01-12 00:47:05 +0000455
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000456static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000457complex_pow(v, w, z)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000458 PyComplexObject *v;
459 PyObject *w;
460 PyComplexObject *z;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000461{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000462 Py_complex p;
463 Py_complex exponent;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000464 long int_exponent;
465
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000466 if ((PyObject *)z!=Py_None) {
467 PyErr_SetString(PyExc_ValueError, "complex modulo");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000468 return NULL;
469 }
470
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000471 PyFPE_START_PROTECT("complex_pow", return 0)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000472 c_error = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000473 exponent = ((PyComplexObject*)w)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000474 int_exponent = (long)exponent.real;
475 if (exponent.imag == 0. && exponent.real == int_exponent)
476 p = c_powi(v->cval,int_exponent);
477 else
478 p = c_pow(v->cval,exponent);
479
Guido van Rossum45b83911997-03-14 04:32:50 +0000480 PyFPE_END_PROTECT(p)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000481 if (c_error == 2) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000482 PyErr_SetString(PyExc_ValueError,
483 "0.0 to a negative or complex power");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000484 return NULL;
485 }
486
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000487 return PyComplex_FromCComplex(p);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000488}
489
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000490static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000491complex_neg(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000492 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000493{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000494 Py_complex neg;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000495 neg.real = -v->cval.real;
496 neg.imag = -v->cval.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000497 return PyComplex_FromCComplex(neg);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000498}
499
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000500static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000501complex_pos(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000502 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000503{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000504 Py_INCREF(v);
505 return (PyObject *)v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000506}
507
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000508static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000509complex_abs(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000510 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000511{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000512 double result;
513 PyFPE_START_PROTECT("complex_abs", return 0)
514 result = hypot(v->cval.real,v->cval.imag);
Guido van Rossum45b83911997-03-14 04:32:50 +0000515 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000516 return PyFloat_FromDouble(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000517}
518
519static int
520complex_nonzero(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000521 PyComplexObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000522{
523 return v->cval.real != 0.0 && v->cval.imag != 0.0;
524}
525
526static int
527complex_coerce(pv, pw)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000528 PyObject **pv;
529 PyObject **pw;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000530{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000531 Py_complex cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000532 cval.imag = 0.;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000533 if (PyInt_Check(*pw)) {
534 cval.real = (double)PyInt_AsLong(*pw);
535 *pw = PyComplex_FromCComplex(cval);
536 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000537 return 0;
538 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000539 else if (PyLong_Check(*pw)) {
540 cval.real = PyLong_AsDouble(*pw);
541 *pw = PyComplex_FromCComplex(cval);
542 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000543 return 0;
544 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000545 else if (PyFloat_Check(*pw)) {
546 cval.real = PyFloat_AsDouble(*pw);
547 *pw = PyComplex_FromCComplex(cval);
548 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000549 return 0;
550 }
551 return 1; /* Can't do it */
552}
553
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000554static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000555complex_int(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000556 PyObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000557{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000558 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000559 "can't convert complex to int; use e.g. int(abs(z))");
560 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000561}
562
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000563static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000564complex_long(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000565 PyObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000566{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000567 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000568 "can't convert complex to long; use e.g. long(abs(z))");
569 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000570}
571
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000572static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000573complex_float(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000574 PyObject *v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000575{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000576 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000577 "can't convert complex to float; use e.g. abs(z)");
578 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000579}
580
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000581static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000582complex_conjugate(self)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000583 PyObject *self;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000584{
Guido van Rossum926518b1996-08-19 19:30:45 +0000585 Py_complex c;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000586 c = ((PyComplexObject *)self)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000587 c.imag = -c.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000588 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000589}
590
591static PyMethodDef complex_methods[] = {
592 {"conjugate", (PyCFunction)complex_conjugate, 1},
593 {NULL, NULL} /* sentinel */
594};
595
596
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000597static PyObject *
Guido van Rossumf9fca921996-01-12 00:47:05 +0000598complex_getattr(self, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000599 PyComplexObject *self;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000600 char *name;
601{
Guido van Rossumf9fca921996-01-12 00:47:05 +0000602 if (strcmp(name, "real") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000603 return (PyObject *)PyFloat_FromDouble(self->cval.real);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000604 else if (strcmp(name, "imag") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000605 return (PyObject *)PyFloat_FromDouble(self->cval.imag);
Guido van Rossumc054d701997-04-01 03:12:33 +0000606 else if (strcmp(name, "__members__") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000607 return Py_BuildValue("[ss]", "imag", "real");
608 return Py_FindMethod(complex_methods, (PyObject *)self, name);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000609}
610
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000611static PyNumberMethods complex_as_number = {
Guido van Rossumf9fca921996-01-12 00:47:05 +0000612 (binaryfunc)complex_add, /*nb_add*/
613 (binaryfunc)complex_sub, /*nb_subtract*/
614 (binaryfunc)complex_mul, /*nb_multiply*/
615 (binaryfunc)complex_div, /*nb_divide*/
Guido van Rossumee09fc11996-09-11 13:55:55 +0000616 (binaryfunc)complex_remainder, /*nb_remainder*/
617 (binaryfunc)complex_divmod, /*nb_divmod*/
Guido van Rossumf9fca921996-01-12 00:47:05 +0000618 (ternaryfunc)complex_pow, /*nb_power*/
619 (unaryfunc)complex_neg, /*nb_negative*/
620 (unaryfunc)complex_pos, /*nb_positive*/
621 (unaryfunc)complex_abs, /*nb_absolute*/
622 (inquiry)complex_nonzero, /*nb_nonzero*/
623 0, /*nb_invert*/
624 0, /*nb_lshift*/
625 0, /*nb_rshift*/
626 0, /*nb_and*/
627 0, /*nb_xor*/
628 0, /*nb_or*/
629 (coercion)complex_coerce, /*nb_coerce*/
630 (unaryfunc)complex_int, /*nb_int*/
631 (unaryfunc)complex_long, /*nb_long*/
632 (unaryfunc)complex_float, /*nb_float*/
633 0, /*nb_oct*/
634 0, /*nb_hex*/
635};
636
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000637PyTypeObject PyComplex_Type = {
638 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000639 0,
640 "complex",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000641 sizeof(PyComplexObject),
Guido van Rossumf9fca921996-01-12 00:47:05 +0000642 0,
643 (destructor)complex_dealloc, /*tp_dealloc*/
644 (printfunc)complex_print, /*tp_print*/
645 (getattrfunc)complex_getattr, /*tp_getattr*/
646 0, /*tp_setattr*/
647 (cmpfunc)complex_compare, /*tp_compare*/
648 (reprfunc)complex_repr, /*tp_repr*/
649 &complex_as_number, /*tp_as_number*/
650 0, /*tp_as_sequence*/
651 0, /*tp_as_mapping*/
652 (hashfunc)complex_hash, /*tp_hash*/
653};
654
655#endif