blob: dc1d83741fca2c2062c99989e94c41953c768a65 [file] [log] [blame]
Guido van Rossum96783941997-05-20 18:21:34 +00001
Guido van Rossumf9fca921996-01-12 00:47:05 +00002/* Complex object implementation */
3
4/* Borrows heavily from floatobject.c */
5
Guido van Rossum96783941997-05-20 18:21:34 +00006/* Submitted by Jim Hugunin */
7
Guido van Rossumf9fca921996-01-12 00:47:05 +00008#ifndef WITHOUT_COMPLEX
9
Guido van Rossumc0b618a1997-05-02 03:12:38 +000010#include "Python.h"
Guido van Rossumf9fca921996-01-12 00:47:05 +000011
Guido van Rossumf9fca921996-01-12 00:47:05 +000012
13/* elementary operations on complex numbers */
14
Guido van Rossum9e720e31996-07-21 02:31:35 +000015static Py_complex c_1 = {1., 0.};
Guido van Rossumf9fca921996-01-12 00:47:05 +000016
Fred Drake4288c802000-07-09 04:36:04 +000017Py_complex c_sum(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +000018{
Guido van Rossum9e720e31996-07-21 02:31:35 +000019 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000020 r.real = a.real + b.real;
21 r.imag = a.imag + b.imag;
22 return r;
23}
24
Fred Drake4288c802000-07-09 04:36:04 +000025Py_complex c_diff(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +000026{
Guido van Rossum9e720e31996-07-21 02:31:35 +000027 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000028 r.real = a.real - b.real;
29 r.imag = a.imag - b.imag;
30 return r;
31}
32
Fred Drake4288c802000-07-09 04:36:04 +000033Py_complex c_neg(Py_complex a)
Guido van Rossumf9fca921996-01-12 00:47:05 +000034{
Guido van Rossum9e720e31996-07-21 02:31:35 +000035 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000036 r.real = -a.real;
37 r.imag = -a.imag;
38 return r;
39}
40
Fred Drake4288c802000-07-09 04:36:04 +000041Py_complex c_prod(Py_complex a, Py_complex 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 - a.imag*b.imag;
45 r.imag = a.real*b.imag + a.imag*b.real;
46 return r;
47}
48
Fred Drake4288c802000-07-09 04:36:04 +000049Py_complex c_quot(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +000050{
Guido van Rossum9e720e31996-07-21 02:31:35 +000051 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000052 double d = b.real*b.real + b.imag*b.imag;
53 if (d == 0.)
Guido van Rossum96783941997-05-20 18:21:34 +000054 errno = EDOM;
Guido van Rossumf9fca921996-01-12 00:47:05 +000055 r.real = (a.real*b.real + a.imag*b.imag)/d;
56 r.imag = (a.imag*b.real - a.real*b.imag)/d;
57 return r;
58}
59
Fred Drake4288c802000-07-09 04:36:04 +000060Py_complex c_pow(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +000061{
Guido van Rossum9e720e31996-07-21 02:31:35 +000062 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000063 double vabs,len,at,phase;
64 if (b.real == 0. && b.imag == 0.) {
65 r.real = 1.;
66 r.imag = 0.;
67 }
68 else if (a.real == 0. && a.imag == 0.) {
69 if (b.imag != 0. || b.real < 0.)
Guido van Rossum96783941997-05-20 18:21:34 +000070 errno = ERANGE;
Guido van Rossumf9fca921996-01-12 00:47:05 +000071 r.real = 0.;
72 r.imag = 0.;
73 }
74 else {
75 vabs = hypot(a.real,a.imag);
76 len = pow(vabs,b.real);
77 at = atan2(a.imag, a.real);
78 phase = at*b.real;
79 if (b.imag != 0.0) {
80 len /= exp(at*b.imag);
81 phase += b.imag*log(vabs);
82 }
83 r.real = len*cos(phase);
84 r.imag = len*sin(phase);
85 }
86 return r;
87}
88
Fred Drake4288c802000-07-09 04:36:04 +000089static Py_complex c_powu(Py_complex x, long n)
Guido van Rossumf9fca921996-01-12 00:47:05 +000090{
Guido van Rossum926518b1996-08-19 19:30:45 +000091 Py_complex r, p;
Guido van Rossumf9fca921996-01-12 00:47:05 +000092 long mask = 1;
Guido van Rossum926518b1996-08-19 19:30:45 +000093 r = c_1;
94 p = x;
Guido van Rossumf9fca921996-01-12 00:47:05 +000095 while (mask > 0 && n >= mask) {
96 if (n & mask)
97 r = c_prod(r,p);
98 mask <<= 1;
99 p = c_prod(p,p);
100 }
101 return r;
102}
103
Fred Drake4288c802000-07-09 04:36:04 +0000104static Py_complex c_powi(Py_complex x, long n)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000105{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000106 Py_complex cn;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000107
108 if (n > 100 || n < -100) {
109 cn.real = (double) n;
110 cn.imag = 0.;
111 return c_pow(x,cn);
112 }
113 else if (n > 0)
114 return c_powu(x,n);
115 else
116 return c_quot(c_1,c_powu(x,-n));
117
118}
119
120PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000121PyComplex_FromCComplex(Py_complex cval)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000122{
Guido van Rossumb18618d2000-05-03 23:44:39 +0000123 register PyComplexObject *op;
124
125 /* PyObject_New is inlined */
126 op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject));
Guido van Rossumf9fca921996-01-12 00:47:05 +0000127 if (op == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000128 return PyErr_NoMemory();
Guido van Rossumb18618d2000-05-03 23:44:39 +0000129 PyObject_INIT(op, &PyComplex_Type);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000130 op->cval = cval;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000131 return (PyObject *) op;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000132}
133
134PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000135PyComplex_FromDoubles(double real, double imag)
Guido van Rossum926518b1996-08-19 19:30:45 +0000136{
137 Py_complex c;
138 c.real = real;
139 c.imag = imag;
140 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000141}
142
143double
Fred Drake4288c802000-07-09 04:36:04 +0000144PyComplex_RealAsDouble(PyObject *op)
Guido van Rossum926518b1996-08-19 19:30:45 +0000145{
146 if (PyComplex_Check(op)) {
147 return ((PyComplexObject *)op)->cval.real;
Fred Drake4288c802000-07-09 04:36:04 +0000148 }
149 else {
Guido van Rossum926518b1996-08-19 19:30:45 +0000150 return PyFloat_AsDouble(op);
151 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000152}
153
154double
Fred Drake4288c802000-07-09 04:36:04 +0000155PyComplex_ImagAsDouble(PyObject *op)
Guido van Rossum926518b1996-08-19 19:30:45 +0000156{
157 if (PyComplex_Check(op)) {
158 return ((PyComplexObject *)op)->cval.imag;
Fred Drake4288c802000-07-09 04:36:04 +0000159 }
160 else {
Guido van Rossum926518b1996-08-19 19:30:45 +0000161 return 0.0;
162 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000163}
164
Guido van Rossum9e720e31996-07-21 02:31:35 +0000165Py_complex
Fred Drake4288c802000-07-09 04:36:04 +0000166PyComplex_AsCComplex(PyObject *op)
Guido van Rossum926518b1996-08-19 19:30:45 +0000167{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000168 Py_complex cv;
Guido van Rossumcf3d1081996-01-12 01:21:14 +0000169 if (PyComplex_Check(op)) {
170 return ((PyComplexObject *)op)->cval;
Fred Drake4288c802000-07-09 04:36:04 +0000171 }
172 else {
Guido van Rossumcf3d1081996-01-12 01:21:14 +0000173 cv.real = PyFloat_AsDouble(op);
174 cv.imag = 0.;
175 return cv;
176 }
177}
178
Guido van Rossumf9fca921996-01-12 00:47:05 +0000179static void
Fred Drake4288c802000-07-09 04:36:04 +0000180complex_dealloc(PyObject *op)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000181{
Guido van Rossumb18618d2000-05-03 23:44:39 +0000182 PyObject_DEL(op);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000183}
184
185
Guido van Rossum363078a1996-05-24 20:45:01 +0000186static void
Fred Drake4288c802000-07-09 04:36:04 +0000187complex_buf_repr(char *buf, PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000188{
189 if (v->cval.real == 0.)
Guido van Rossum72418791996-01-25 16:21:31 +0000190 sprintf(buf, "%.12gj", v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000191 else
Guido van Rossum72418791996-01-25 16:21:31 +0000192 sprintf(buf, "(%.12g%+.12gj)", v->cval.real, v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000193}
194
195static int
Fred Drake4288c802000-07-09 04:36:04 +0000196complex_print(PyComplexObject *v, FILE *fp, int flags)
197 /* flags -- not used but required by interface */
Guido van Rossumf9fca921996-01-12 00:47:05 +0000198{
199 char buf[100];
200 complex_buf_repr(buf, v);
201 fputs(buf, fp);
202 return 0;
203}
204
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000205static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000206complex_repr(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000207{
208 char buf[100];
209 complex_buf_repr(buf, v);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000210 return PyString_FromString(buf);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000211}
212
213static int
Fred Drake4288c802000-07-09 04:36:04 +0000214complex_compare(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000215{
Fred Drake4288c802000-07-09 04:36:04 +0000216 /* Note: "greater" and "smaller" have no meaning for complex numbers,
217 but Python requires that they be defined nevertheless. */
Guido van Rossum926518b1996-08-19 19:30:45 +0000218 Py_complex i, j;
219 i = v->cval;
220 j = w->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000221 if (i.real == j.real && i.imag == j.imag)
Fred Drake4288c802000-07-09 04:36:04 +0000222 return 0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000223 else if (i.real != j.real)
Fred Drake4288c802000-07-09 04:36:04 +0000224 return (i.real < j.real) ? -1 : 1;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000225 else
Fred Drake4288c802000-07-09 04:36:04 +0000226 return (i.imag < j.imag) ? -1 : 1;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000227}
228
229static long
Fred Drake4288c802000-07-09 04:36:04 +0000230complex_hash(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000231{
Tim Peters39dce292000-08-15 03:34:48 +0000232 long hashreal, hashimag, combined;
233 hashreal = _Py_HashDouble(v->cval.real);
234 if (hashreal == -1)
235 return -1;
236 hashimag = _Py_HashDouble(v->cval.imag);
237 if (hashimag == -1)
238 return -1;
239 /* Note: if the imaginary part is 0, hashimag is 0 now,
240 * so the following returns hashreal unchanged. This is
241 * important because numbers of different types that
242 * compare equal must have the same hash value, so that
243 * hash(x + 0*j) must equal hash(x).
244 */
245 combined = hashreal + 1000003 * hashimag;
246 if (combined == -1)
247 combined = -2;
248 return combined;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000249}
250
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000251static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000252complex_add(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000253{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000254 Py_complex result;
255 PyFPE_START_PROTECT("complex_add", return 0)
256 result = c_sum(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000257 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000258 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000259}
260
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000261static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000262complex_sub(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000263{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000264 Py_complex result;
265 PyFPE_START_PROTECT("complex_sub", return 0)
266 result = c_diff(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000267 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000268 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000269}
270
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000271static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000272complex_mul(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000273{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000274 Py_complex result;
275 PyFPE_START_PROTECT("complex_mul", return 0)
276 result = c_prod(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000277 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000278 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000279}
280
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000281static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000282complex_div(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000283{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000284 Py_complex quot;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000285 PyFPE_START_PROTECT("complex_div", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000286 errno = 0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000287 quot = c_quot(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000288 PyFPE_END_PROTECT(quot)
Guido van Rossum96783941997-05-20 18:21:34 +0000289 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000290 PyErr_SetString(PyExc_ZeroDivisionError, "complex division");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000291 return NULL;
292 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000293 return PyComplex_FromCComplex(quot);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000294}
295
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000296static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000297complex_remainder(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumee09fc11996-09-11 13:55:55 +0000298{
Guido van Rossum3be12e91996-09-12 20:56:18 +0000299 Py_complex div, mod;
Guido van Rossum96783941997-05-20 18:21:34 +0000300 errno = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000301 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
Guido van Rossum96783941997-05-20 18:21:34 +0000302 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000303 PyErr_SetString(PyExc_ZeroDivisionError, "complex remainder");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000304 return NULL;
305 }
306 div.real = floor(div.real); /* Use the floor of the real part. */
307 div.imag = 0.0;
308 mod = c_diff(v->cval, c_prod(w->cval, div));
309
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000310 return PyComplex_FromCComplex(mod);
Guido van Rossumee09fc11996-09-11 13:55:55 +0000311}
312
Guido van Rossumee09fc11996-09-11 13:55:55 +0000313
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000314static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000315complex_divmod(PyComplexObject *v, PyComplexObject *w)
Guido van Rossum3be12e91996-09-12 20:56:18 +0000316{
317 Py_complex div, mod;
318 PyObject *d, *m, *z;
Guido van Rossum96783941997-05-20 18:21:34 +0000319 errno = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000320 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
Guido van Rossum96783941997-05-20 18:21:34 +0000321 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000322 PyErr_SetString(PyExc_ZeroDivisionError, "complex divmod()");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000323 return NULL;
324 }
325 div.real = floor(div.real); /* Use the floor of the real part. */
326 div.imag = 0.0;
327 mod = c_diff(v->cval, c_prod(w->cval, div));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000328 d = PyComplex_FromCComplex(div);
329 m = PyComplex_FromCComplex(mod);
330 z = Py_BuildValue("(OO)", d, m);
Guido van Rossum3be12e91996-09-12 20:56:18 +0000331 Py_XDECREF(d);
332 Py_XDECREF(m);
333 return z;
334}
Guido van Rossumf9fca921996-01-12 00:47:05 +0000335
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000336static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000337complex_pow(PyComplexObject *v, PyObject *w, PyComplexObject *z)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000338{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000339 Py_complex p;
340 Py_complex exponent;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000341 long int_exponent;
342
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000343 if ((PyObject *)z!=Py_None) {
344 PyErr_SetString(PyExc_ValueError, "complex modulo");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000345 return NULL;
346 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000347 PyFPE_START_PROTECT("complex_pow", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000348 errno = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000349 exponent = ((PyComplexObject*)w)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000350 int_exponent = (long)exponent.real;
351 if (exponent.imag == 0. && exponent.real == int_exponent)
352 p = c_powi(v->cval,int_exponent);
353 else
354 p = c_pow(v->cval,exponent);
355
Guido van Rossum45b83911997-03-14 04:32:50 +0000356 PyFPE_END_PROTECT(p)
Guido van Rossum96783941997-05-20 18:21:34 +0000357 if (errno == ERANGE) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000358 PyErr_SetString(PyExc_ValueError,
359 "0.0 to a negative or complex power");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000360 return NULL;
361 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000362 return PyComplex_FromCComplex(p);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000363}
364
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000365static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000366complex_neg(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000367{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000368 Py_complex neg;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000369 neg.real = -v->cval.real;
370 neg.imag = -v->cval.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000371 return PyComplex_FromCComplex(neg);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000372}
373
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000374static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000375complex_pos(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000376{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000377 Py_INCREF(v);
378 return (PyObject *)v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000379}
380
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000381static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000382complex_abs(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000383{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000384 double result;
385 PyFPE_START_PROTECT("complex_abs", return 0)
386 result = hypot(v->cval.real,v->cval.imag);
Guido van Rossum45b83911997-03-14 04:32:50 +0000387 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000388 return PyFloat_FromDouble(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000389}
390
391static int
Fred Drake4288c802000-07-09 04:36:04 +0000392complex_nonzero(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000393{
Guido van Rossum3bbef601999-01-25 19:42:19 +0000394 return v->cval.real != 0.0 || v->cval.imag != 0.0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000395}
396
397static int
Fred Drake4288c802000-07-09 04:36:04 +0000398complex_coerce(PyObject **pv, PyObject **pw)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000399{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000400 Py_complex cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000401 cval.imag = 0.;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000402 if (PyInt_Check(*pw)) {
403 cval.real = (double)PyInt_AsLong(*pw);
404 *pw = PyComplex_FromCComplex(cval);
405 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000406 return 0;
407 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000408 else if (PyLong_Check(*pw)) {
409 cval.real = PyLong_AsDouble(*pw);
410 *pw = PyComplex_FromCComplex(cval);
411 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000412 return 0;
413 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000414 else if (PyFloat_Check(*pw)) {
415 cval.real = PyFloat_AsDouble(*pw);
416 *pw = PyComplex_FromCComplex(cval);
417 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000418 return 0;
419 }
420 return 1; /* Can't do it */
421}
422
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000423static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000424complex_int(PyObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000425{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000426 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000427 "can't convert complex to int; use e.g. int(abs(z))");
428 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000429}
430
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000431static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000432complex_long(PyObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000433{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000434 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000435 "can't convert complex to long; use e.g. long(abs(z))");
436 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000437}
438
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000439static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000440complex_float(PyObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000441{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000442 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000443 "can't convert complex to float; use e.g. abs(z)");
444 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000445}
446
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000447static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000448complex_conjugate(PyObject *self, PyObject *args)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000449{
Guido van Rossum926518b1996-08-19 19:30:45 +0000450 Py_complex c;
Guido van Rossum43713e52000-02-29 13:59:29 +0000451 if (!PyArg_ParseTuple(args, ":conjugate"))
Guido van Rossum8530ef61998-05-07 16:29:10 +0000452 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000453 c = ((PyComplexObject *)self)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000454 c.imag = -c.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000455 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000456}
457
458static PyMethodDef complex_methods[] = {
Guido van Rossum8530ef61998-05-07 16:29:10 +0000459 {"conjugate", complex_conjugate, 1},
Guido van Rossumf9fca921996-01-12 00:47:05 +0000460 {NULL, NULL} /* sentinel */
461};
462
463
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000464static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000465complex_getattr(PyComplexObject *self, char *name)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000466{
Guido van Rossumf9fca921996-01-12 00:47:05 +0000467 if (strcmp(name, "real") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000468 return (PyObject *)PyFloat_FromDouble(self->cval.real);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000469 else if (strcmp(name, "imag") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000470 return (PyObject *)PyFloat_FromDouble(self->cval.imag);
Guido van Rossumc054d701997-04-01 03:12:33 +0000471 else if (strcmp(name, "__members__") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000472 return Py_BuildValue("[ss]", "imag", "real");
473 return Py_FindMethod(complex_methods, (PyObject *)self, name);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000474}
475
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000476static PyNumberMethods complex_as_number = {
Guido van Rossumf9fca921996-01-12 00:47:05 +0000477 (binaryfunc)complex_add, /*nb_add*/
478 (binaryfunc)complex_sub, /*nb_subtract*/
479 (binaryfunc)complex_mul, /*nb_multiply*/
480 (binaryfunc)complex_div, /*nb_divide*/
Guido van Rossumee09fc11996-09-11 13:55:55 +0000481 (binaryfunc)complex_remainder, /*nb_remainder*/
482 (binaryfunc)complex_divmod, /*nb_divmod*/
Guido van Rossumf9fca921996-01-12 00:47:05 +0000483 (ternaryfunc)complex_pow, /*nb_power*/
484 (unaryfunc)complex_neg, /*nb_negative*/
485 (unaryfunc)complex_pos, /*nb_positive*/
486 (unaryfunc)complex_abs, /*nb_absolute*/
487 (inquiry)complex_nonzero, /*nb_nonzero*/
488 0, /*nb_invert*/
489 0, /*nb_lshift*/
490 0, /*nb_rshift*/
491 0, /*nb_and*/
492 0, /*nb_xor*/
493 0, /*nb_or*/
494 (coercion)complex_coerce, /*nb_coerce*/
495 (unaryfunc)complex_int, /*nb_int*/
496 (unaryfunc)complex_long, /*nb_long*/
497 (unaryfunc)complex_float, /*nb_float*/
498 0, /*nb_oct*/
499 0, /*nb_hex*/
500};
501
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000502PyTypeObject PyComplex_Type = {
503 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000504 0,
505 "complex",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000506 sizeof(PyComplexObject),
Guido van Rossumf9fca921996-01-12 00:47:05 +0000507 0,
508 (destructor)complex_dealloc, /*tp_dealloc*/
509 (printfunc)complex_print, /*tp_print*/
510 (getattrfunc)complex_getattr, /*tp_getattr*/
511 0, /*tp_setattr*/
512 (cmpfunc)complex_compare, /*tp_compare*/
513 (reprfunc)complex_repr, /*tp_repr*/
514 &complex_as_number, /*tp_as_number*/
515 0, /*tp_as_sequence*/
516 0, /*tp_as_mapping*/
517 (hashfunc)complex_hash, /*tp_hash*/
518};
519
520#endif