blob: a0dd9d5fffd1f012182c25b2e1e70d913fbc964b [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
Guido van Rossumf9fca921996-01-12 00:47:05 +0000213static long
Fred Drake4288c802000-07-09 04:36:04 +0000214complex_hash(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000215{
Tim Peters39dce292000-08-15 03:34:48 +0000216 long hashreal, hashimag, combined;
217 hashreal = _Py_HashDouble(v->cval.real);
218 if (hashreal == -1)
219 return -1;
220 hashimag = _Py_HashDouble(v->cval.imag);
221 if (hashimag == -1)
222 return -1;
223 /* Note: if the imaginary part is 0, hashimag is 0 now,
224 * so the following returns hashreal unchanged. This is
225 * important because numbers of different types that
226 * compare equal must have the same hash value, so that
227 * hash(x + 0*j) must equal hash(x).
228 */
229 combined = hashreal + 1000003 * hashimag;
230 if (combined == -1)
231 combined = -2;
232 return combined;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000233}
234
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000235static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000236complex_add(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000237{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000238 Py_complex result;
239 PyFPE_START_PROTECT("complex_add", return 0)
240 result = c_sum(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000241 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000242 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000243}
244
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000245static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000246complex_sub(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000247{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000248 Py_complex result;
249 PyFPE_START_PROTECT("complex_sub", return 0)
250 result = c_diff(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000251 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000252 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000253}
254
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000255static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000256complex_mul(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000257{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000258 Py_complex result;
259 PyFPE_START_PROTECT("complex_mul", return 0)
260 result = c_prod(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000261 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000262 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000263}
264
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000265static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000266complex_div(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000267{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000268 Py_complex quot;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000269 PyFPE_START_PROTECT("complex_div", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000270 errno = 0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000271 quot = c_quot(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000272 PyFPE_END_PROTECT(quot)
Guido van Rossum96783941997-05-20 18:21:34 +0000273 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000274 PyErr_SetString(PyExc_ZeroDivisionError, "complex division");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000275 return NULL;
276 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000277 return PyComplex_FromCComplex(quot);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000278}
279
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000280static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000281complex_remainder(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumee09fc11996-09-11 13:55:55 +0000282{
Guido van Rossum3be12e91996-09-12 20:56:18 +0000283 Py_complex div, mod;
Guido van Rossum96783941997-05-20 18:21:34 +0000284 errno = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000285 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
Guido van Rossum96783941997-05-20 18:21:34 +0000286 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000287 PyErr_SetString(PyExc_ZeroDivisionError, "complex remainder");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000288 return NULL;
289 }
290 div.real = floor(div.real); /* Use the floor of the real part. */
291 div.imag = 0.0;
292 mod = c_diff(v->cval, c_prod(w->cval, div));
293
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000294 return PyComplex_FromCComplex(mod);
Guido van Rossumee09fc11996-09-11 13:55:55 +0000295}
296
Guido van Rossumee09fc11996-09-11 13:55:55 +0000297
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000298static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000299complex_divmod(PyComplexObject *v, PyComplexObject *w)
Guido van Rossum3be12e91996-09-12 20:56:18 +0000300{
301 Py_complex div, mod;
302 PyObject *d, *m, *z;
Guido van Rossum96783941997-05-20 18:21:34 +0000303 errno = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000304 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
Guido van Rossum96783941997-05-20 18:21:34 +0000305 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000306 PyErr_SetString(PyExc_ZeroDivisionError, "complex divmod()");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000307 return NULL;
308 }
309 div.real = floor(div.real); /* Use the floor of the real part. */
310 div.imag = 0.0;
311 mod = c_diff(v->cval, c_prod(w->cval, div));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000312 d = PyComplex_FromCComplex(div);
313 m = PyComplex_FromCComplex(mod);
314 z = Py_BuildValue("(OO)", d, m);
Guido van Rossum3be12e91996-09-12 20:56:18 +0000315 Py_XDECREF(d);
316 Py_XDECREF(m);
317 return z;
318}
Guido van Rossumf9fca921996-01-12 00:47:05 +0000319
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000320static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000321complex_pow(PyComplexObject *v, PyObject *w, PyComplexObject *z)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000322{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000323 Py_complex p;
324 Py_complex exponent;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000325 long int_exponent;
326
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000327 if ((PyObject *)z!=Py_None) {
328 PyErr_SetString(PyExc_ValueError, "complex modulo");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000329 return NULL;
330 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000331 PyFPE_START_PROTECT("complex_pow", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000332 errno = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000333 exponent = ((PyComplexObject*)w)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000334 int_exponent = (long)exponent.real;
335 if (exponent.imag == 0. && exponent.real == int_exponent)
336 p = c_powi(v->cval,int_exponent);
337 else
338 p = c_pow(v->cval,exponent);
339
Guido van Rossum45b83911997-03-14 04:32:50 +0000340 PyFPE_END_PROTECT(p)
Guido van Rossum96783941997-05-20 18:21:34 +0000341 if (errno == ERANGE) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000342 PyErr_SetString(PyExc_ValueError,
343 "0.0 to a negative or complex power");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000344 return NULL;
345 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000346 return PyComplex_FromCComplex(p);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000347}
348
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000349static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000350complex_neg(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000351{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000352 Py_complex neg;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000353 neg.real = -v->cval.real;
354 neg.imag = -v->cval.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000355 return PyComplex_FromCComplex(neg);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000356}
357
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000358static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000359complex_pos(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000360{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000361 Py_INCREF(v);
362 return (PyObject *)v;
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_abs(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000367{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000368 double result;
369 PyFPE_START_PROTECT("complex_abs", return 0)
370 result = hypot(v->cval.real,v->cval.imag);
Guido van Rossum45b83911997-03-14 04:32:50 +0000371 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000372 return PyFloat_FromDouble(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000373}
374
375static int
Fred Drake4288c802000-07-09 04:36:04 +0000376complex_nonzero(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000377{
Guido van Rossum3bbef601999-01-25 19:42:19 +0000378 return v->cval.real != 0.0 || v->cval.imag != 0.0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000379}
380
381static int
Fred Drake4288c802000-07-09 04:36:04 +0000382complex_coerce(PyObject **pv, PyObject **pw)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000383{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000384 Py_complex cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000385 cval.imag = 0.;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000386 if (PyInt_Check(*pw)) {
387 cval.real = (double)PyInt_AsLong(*pw);
388 *pw = PyComplex_FromCComplex(cval);
389 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000390 return 0;
391 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000392 else if (PyLong_Check(*pw)) {
393 cval.real = PyLong_AsDouble(*pw);
394 *pw = PyComplex_FromCComplex(cval);
395 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000396 return 0;
397 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000398 else if (PyFloat_Check(*pw)) {
399 cval.real = PyFloat_AsDouble(*pw);
400 *pw = PyComplex_FromCComplex(cval);
401 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000402 return 0;
403 }
404 return 1; /* Can't do it */
405}
406
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000407static PyObject *
Guido van Rossumbe4cbb12001-01-18 01:12:39 +0000408complex_richcompare(PyObject *v, PyObject *w, int op)
409{
410 int c;
411 Py_complex i, j;
412 PyObject *res;
413
414 if (op != Py_EQ && op != Py_NE) {
415 PyErr_SetString(PyExc_TypeError,
416 "cannot compare complex numbers using <, <=, >, >=");
417 return NULL;
418 }
419
420 c = PyNumber_CoerceEx(&v, &w);
421 if (c < 0)
422 return NULL;
423 if (c > 0) {
424 Py_INCREF(Py_NotImplemented);
425 return Py_NotImplemented;
426 }
427 if (!PyComplex_Check(v) || !PyComplex_Check(w)) {
428 Py_DECREF(v);
429 Py_DECREF(w);
430 Py_INCREF(Py_NotImplemented);
431 return Py_NotImplemented;
432 }
433
434 i = ((PyComplexObject *)v)->cval;
435 j = ((PyComplexObject *)w)->cval;
436 Py_DECREF(v);
437 Py_DECREF(w);
438
439 if ((i.real == j.real && i.imag == j.imag) == (op == Py_EQ))
440 res = Py_True;
441 else
442 res = Py_False;
443
444 Py_INCREF(res);
445 return res;
446}
447
448static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000449complex_int(PyObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000450{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000451 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000452 "can't convert complex to int; use e.g. int(abs(z))");
453 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000454}
455
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000456static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000457complex_long(PyObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000458{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000459 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000460 "can't convert complex to long; use e.g. long(abs(z))");
461 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000462}
463
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000464static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000465complex_float(PyObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000466{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000467 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000468 "can't convert complex to float; use e.g. abs(z)");
469 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000470}
471
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000472static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000473complex_conjugate(PyObject *self, PyObject *args)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000474{
Guido van Rossum926518b1996-08-19 19:30:45 +0000475 Py_complex c;
Guido van Rossum43713e52000-02-29 13:59:29 +0000476 if (!PyArg_ParseTuple(args, ":conjugate"))
Guido van Rossum8530ef61998-05-07 16:29:10 +0000477 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000478 c = ((PyComplexObject *)self)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000479 c.imag = -c.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000480 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000481}
482
483static PyMethodDef complex_methods[] = {
Guido van Rossum8530ef61998-05-07 16:29:10 +0000484 {"conjugate", complex_conjugate, 1},
Guido van Rossumf9fca921996-01-12 00:47:05 +0000485 {NULL, NULL} /* sentinel */
486};
487
488
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000489static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000490complex_getattr(PyComplexObject *self, char *name)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000491{
Guido van Rossumf9fca921996-01-12 00:47:05 +0000492 if (strcmp(name, "real") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000493 return (PyObject *)PyFloat_FromDouble(self->cval.real);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000494 else if (strcmp(name, "imag") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000495 return (PyObject *)PyFloat_FromDouble(self->cval.imag);
Guido van Rossumc054d701997-04-01 03:12:33 +0000496 else if (strcmp(name, "__members__") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000497 return Py_BuildValue("[ss]", "imag", "real");
498 return Py_FindMethod(complex_methods, (PyObject *)self, name);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000499}
500
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000501static PyNumberMethods complex_as_number = {
Guido van Rossumbe4cbb12001-01-18 01:12:39 +0000502 (binaryfunc)complex_add, /* nb_add */
503 (binaryfunc)complex_sub, /* nb_subtract */
504 (binaryfunc)complex_mul, /* nb_multiply */
505 (binaryfunc)complex_div, /* nb_divide */
506 (binaryfunc)complex_remainder, /* nb_remainder */
507 (binaryfunc)complex_divmod, /* nb_divmod */
508 (ternaryfunc)complex_pow, /* nb_power */
509 (unaryfunc)complex_neg, /* nb_negative */
510 (unaryfunc)complex_pos, /* nb_positive */
511 (unaryfunc)complex_abs, /* nb_absolute */
512 (inquiry)complex_nonzero, /* nb_nonzero */
513 0, /* nb_invert */
514 0, /* nb_lshift */
515 0, /* nb_rshift */
516 0, /* nb_and */
517 0, /* nb_xor */
518 0, /* nb_or */
519 (coercion)complex_coerce, /* nb_coerce */
520 (unaryfunc)complex_int, /* nb_int */
521 (unaryfunc)complex_long, /* nb_long */
522 (unaryfunc)complex_float, /* nb_float */
523 0, /* nb_oct */
524 0, /* nb_hex */
Guido van Rossumf9fca921996-01-12 00:47:05 +0000525};
526
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000527PyTypeObject PyComplex_Type = {
528 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000529 0,
530 "complex",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000531 sizeof(PyComplexObject),
Guido van Rossumf9fca921996-01-12 00:47:05 +0000532 0,
Guido van Rossumbe4cbb12001-01-18 01:12:39 +0000533 (destructor)complex_dealloc, /* tp_dealloc */
534 (printfunc)complex_print, /* tp_print */
535 (getattrfunc)complex_getattr, /* tp_getattr */
536 0, /* tp_setattr */
537 0, /* tp_compare */
538 (reprfunc)complex_repr, /* tp_repr */
539 &complex_as_number, /* tp_as_number */
540 0, /* tp_as_sequence */
541 0, /* tp_as_mapping */
542 (hashfunc)complex_hash, /* tp_hash */
543 0, /* tp_call */
544 0, /* tp_str */
545 0, /* tp_getattro */
546 0, /* tp_setattro */
547 0, /* tp_as_buffer */
548 Py_TPFLAGS_DEFAULT, /* tp_flags */
549 0, /* tp_doc */
550 0, /* tp_traverse */
551 0, /* tp_clear */
552 complex_richcompare, /* tp_richcompare */
Guido van Rossumf9fca921996-01-12 00:47:05 +0000553};
554
555#endif