blob: 3c9830f6b196ae871433b55f7ee5f8b46486dc8a [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#ifdef HAVE_LIMITS_H
13#include <limits.h>
14#endif
15
Guido van Rossumf9fca921996-01-12 00:47:05 +000016
17/* elementary operations on complex numbers */
18
Guido van Rossum9e720e31996-07-21 02:31:35 +000019static Py_complex c_1 = {1., 0.};
Guido van Rossumf9fca921996-01-12 00:47:05 +000020
Fred Drake4288c802000-07-09 04:36:04 +000021Py_complex c_sum(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +000022{
Guido van Rossum9e720e31996-07-21 02:31:35 +000023 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000024 r.real = a.real + b.real;
25 r.imag = a.imag + b.imag;
26 return r;
27}
28
Fred Drake4288c802000-07-09 04:36:04 +000029Py_complex c_diff(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +000030{
Guido van Rossum9e720e31996-07-21 02:31:35 +000031 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000032 r.real = a.real - b.real;
33 r.imag = a.imag - b.imag;
34 return r;
35}
36
Fred Drake4288c802000-07-09 04:36:04 +000037Py_complex c_neg(Py_complex a)
Guido van Rossumf9fca921996-01-12 00:47:05 +000038{
Guido van Rossum9e720e31996-07-21 02:31:35 +000039 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000040 r.real = -a.real;
41 r.imag = -a.imag;
42 return r;
43}
44
Fred Drake4288c802000-07-09 04:36:04 +000045Py_complex c_prod(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +000046{
Guido van Rossum9e720e31996-07-21 02:31:35 +000047 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000048 r.real = a.real*b.real - a.imag*b.imag;
49 r.imag = a.real*b.imag + a.imag*b.real;
50 return r;
51}
52
Fred Drake4288c802000-07-09 04:36:04 +000053Py_complex c_quot(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +000054{
Guido van Rossum9e720e31996-07-21 02:31:35 +000055 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000056 double d = b.real*b.real + b.imag*b.imag;
57 if (d == 0.)
Guido van Rossum96783941997-05-20 18:21:34 +000058 errno = EDOM;
Guido van Rossumf9fca921996-01-12 00:47:05 +000059 r.real = (a.real*b.real + a.imag*b.imag)/d;
60 r.imag = (a.imag*b.real - a.real*b.imag)/d;
61 return r;
62}
63
Fred Drake4288c802000-07-09 04:36:04 +000064Py_complex c_pow(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +000065{
Guido van Rossum9e720e31996-07-21 02:31:35 +000066 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000067 double vabs,len,at,phase;
68 if (b.real == 0. && b.imag == 0.) {
69 r.real = 1.;
70 r.imag = 0.;
71 }
72 else if (a.real == 0. && a.imag == 0.) {
73 if (b.imag != 0. || b.real < 0.)
Guido van Rossum96783941997-05-20 18:21:34 +000074 errno = ERANGE;
Guido van Rossumf9fca921996-01-12 00:47:05 +000075 r.real = 0.;
76 r.imag = 0.;
77 }
78 else {
79 vabs = hypot(a.real,a.imag);
80 len = pow(vabs,b.real);
81 at = atan2(a.imag, a.real);
82 phase = at*b.real;
83 if (b.imag != 0.0) {
84 len /= exp(at*b.imag);
85 phase += b.imag*log(vabs);
86 }
87 r.real = len*cos(phase);
88 r.imag = len*sin(phase);
89 }
90 return r;
91}
92
Fred Drake4288c802000-07-09 04:36:04 +000093static Py_complex c_powu(Py_complex x, long n)
Guido van Rossumf9fca921996-01-12 00:47:05 +000094{
Guido van Rossum926518b1996-08-19 19:30:45 +000095 Py_complex r, p;
Guido van Rossumf9fca921996-01-12 00:47:05 +000096 long mask = 1;
Guido van Rossum926518b1996-08-19 19:30:45 +000097 r = c_1;
98 p = x;
Guido van Rossumf9fca921996-01-12 00:47:05 +000099 while (mask > 0 && n >= mask) {
100 if (n & mask)
101 r = c_prod(r,p);
102 mask <<= 1;
103 p = c_prod(p,p);
104 }
105 return r;
106}
107
Fred Drake4288c802000-07-09 04:36:04 +0000108static Py_complex c_powi(Py_complex x, long n)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000109{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000110 Py_complex cn;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000111
112 if (n > 100 || n < -100) {
113 cn.real = (double) n;
114 cn.imag = 0.;
115 return c_pow(x,cn);
116 }
117 else if (n > 0)
118 return c_powu(x,n);
119 else
120 return c_quot(c_1,c_powu(x,-n));
121
122}
123
124PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000125PyComplex_FromCComplex(Py_complex cval)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000126{
Guido van Rossumb18618d2000-05-03 23:44:39 +0000127 register PyComplexObject *op;
128
129 /* PyObject_New is inlined */
130 op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject));
Guido van Rossumf9fca921996-01-12 00:47:05 +0000131 if (op == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000132 return PyErr_NoMemory();
Guido van Rossumb18618d2000-05-03 23:44:39 +0000133 PyObject_INIT(op, &PyComplex_Type);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000134 op->cval = cval;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000135 return (PyObject *) op;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000136}
137
138PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000139PyComplex_FromDoubles(double real, double imag)
Guido van Rossum926518b1996-08-19 19:30:45 +0000140{
141 Py_complex c;
142 c.real = real;
143 c.imag = imag;
144 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000145}
146
147double
Fred Drake4288c802000-07-09 04:36:04 +0000148PyComplex_RealAsDouble(PyObject *op)
Guido van Rossum926518b1996-08-19 19:30:45 +0000149{
150 if (PyComplex_Check(op)) {
151 return ((PyComplexObject *)op)->cval.real;
Fred Drake4288c802000-07-09 04:36:04 +0000152 }
153 else {
Guido van Rossum926518b1996-08-19 19:30:45 +0000154 return PyFloat_AsDouble(op);
155 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000156}
157
158double
Fred Drake4288c802000-07-09 04:36:04 +0000159PyComplex_ImagAsDouble(PyObject *op)
Guido van Rossum926518b1996-08-19 19:30:45 +0000160{
161 if (PyComplex_Check(op)) {
162 return ((PyComplexObject *)op)->cval.imag;
Fred Drake4288c802000-07-09 04:36:04 +0000163 }
164 else {
Guido van Rossum926518b1996-08-19 19:30:45 +0000165 return 0.0;
166 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000167}
168
Guido van Rossum9e720e31996-07-21 02:31:35 +0000169Py_complex
Fred Drake4288c802000-07-09 04:36:04 +0000170PyComplex_AsCComplex(PyObject *op)
Guido van Rossum926518b1996-08-19 19:30:45 +0000171{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000172 Py_complex cv;
Guido van Rossumcf3d1081996-01-12 01:21:14 +0000173 if (PyComplex_Check(op)) {
174 return ((PyComplexObject *)op)->cval;
Fred Drake4288c802000-07-09 04:36:04 +0000175 }
176 else {
Guido van Rossumcf3d1081996-01-12 01:21:14 +0000177 cv.real = PyFloat_AsDouble(op);
178 cv.imag = 0.;
179 return cv;
180 }
181}
182
Guido van Rossumf9fca921996-01-12 00:47:05 +0000183static void
Fred Drake4288c802000-07-09 04:36:04 +0000184complex_dealloc(PyObject *op)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000185{
Guido van Rossumb18618d2000-05-03 23:44:39 +0000186 PyObject_DEL(op);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000187}
188
189
Guido van Rossum363078a1996-05-24 20:45:01 +0000190static void
Fred Drake4288c802000-07-09 04:36:04 +0000191complex_buf_repr(char *buf, PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000192{
193 if (v->cval.real == 0.)
Guido van Rossum72418791996-01-25 16:21:31 +0000194 sprintf(buf, "%.12gj", v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000195 else
Guido van Rossum72418791996-01-25 16:21:31 +0000196 sprintf(buf, "(%.12g%+.12gj)", v->cval.real, v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000197}
198
199static int
Fred Drake4288c802000-07-09 04:36:04 +0000200complex_print(PyComplexObject *v, FILE *fp, int flags)
201 /* flags -- not used but required by interface */
Guido van Rossumf9fca921996-01-12 00:47:05 +0000202{
203 char buf[100];
204 complex_buf_repr(buf, v);
205 fputs(buf, fp);
206 return 0;
207}
208
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000209static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000210complex_repr(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000211{
212 char buf[100];
213 complex_buf_repr(buf, v);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000214 return PyString_FromString(buf);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000215}
216
217static int
Fred Drake4288c802000-07-09 04:36:04 +0000218complex_compare(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000219{
Fred Drake4288c802000-07-09 04:36:04 +0000220 /* Note: "greater" and "smaller" have no meaning for complex numbers,
221 but Python requires that they be defined nevertheless. */
Guido van Rossum926518b1996-08-19 19:30:45 +0000222 Py_complex i, j;
223 i = v->cval;
224 j = w->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000225 if (i.real == j.real && i.imag == j.imag)
Fred Drake4288c802000-07-09 04:36:04 +0000226 return 0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000227 else if (i.real != j.real)
Fred Drake4288c802000-07-09 04:36:04 +0000228 return (i.real < j.real) ? -1 : 1;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000229 else
Fred Drake4288c802000-07-09 04:36:04 +0000230 return (i.imag < j.imag) ? -1 : 1;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000231}
232
233static long
Fred Drake4288c802000-07-09 04:36:04 +0000234complex_hash(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000235{
Tim Peters39dce292000-08-15 03:34:48 +0000236 long hashreal, hashimag, combined;
237 hashreal = _Py_HashDouble(v->cval.real);
238 if (hashreal == -1)
239 return -1;
240 hashimag = _Py_HashDouble(v->cval.imag);
241 if (hashimag == -1)
242 return -1;
243 /* Note: if the imaginary part is 0, hashimag is 0 now,
244 * so the following returns hashreal unchanged. This is
245 * important because numbers of different types that
246 * compare equal must have the same hash value, so that
247 * hash(x + 0*j) must equal hash(x).
248 */
249 combined = hashreal + 1000003 * hashimag;
250 if (combined == -1)
251 combined = -2;
252 return combined;
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_add(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_add", return 0)
260 result = c_sum(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_sub(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000267{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000268 Py_complex result;
269 PyFPE_START_PROTECT("complex_sub", return 0)
270 result = c_diff(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000271 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000272 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000273}
274
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000275static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000276complex_mul(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000277{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000278 Py_complex result;
279 PyFPE_START_PROTECT("complex_mul", return 0)
280 result = c_prod(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000281 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000282 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000283}
284
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000285static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000286complex_div(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000287{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000288 Py_complex quot;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000289 PyFPE_START_PROTECT("complex_div", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000290 errno = 0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000291 quot = c_quot(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000292 PyFPE_END_PROTECT(quot)
Guido van Rossum96783941997-05-20 18:21:34 +0000293 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000294 PyErr_SetString(PyExc_ZeroDivisionError, "complex division");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000295 return NULL;
296 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000297 return PyComplex_FromCComplex(quot);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000298}
299
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000300static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000301complex_remainder(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumee09fc11996-09-11 13:55:55 +0000302{
Guido van Rossum3be12e91996-09-12 20:56:18 +0000303 Py_complex div, mod;
Guido van Rossum96783941997-05-20 18:21:34 +0000304 errno = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000305 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
Guido van Rossum96783941997-05-20 18:21:34 +0000306 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000307 PyErr_SetString(PyExc_ZeroDivisionError, "complex remainder");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000308 return NULL;
309 }
310 div.real = floor(div.real); /* Use the floor of the real part. */
311 div.imag = 0.0;
312 mod = c_diff(v->cval, c_prod(w->cval, div));
313
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000314 return PyComplex_FromCComplex(mod);
Guido van Rossumee09fc11996-09-11 13:55:55 +0000315}
316
Guido van Rossumee09fc11996-09-11 13:55:55 +0000317
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000318static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000319complex_divmod(PyComplexObject *v, PyComplexObject *w)
Guido van Rossum3be12e91996-09-12 20:56:18 +0000320{
321 Py_complex div, mod;
322 PyObject *d, *m, *z;
Guido van Rossum96783941997-05-20 18:21:34 +0000323 errno = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000324 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
Guido van Rossum96783941997-05-20 18:21:34 +0000325 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000326 PyErr_SetString(PyExc_ZeroDivisionError, "complex divmod()");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000327 return NULL;
328 }
329 div.real = floor(div.real); /* Use the floor of the real part. */
330 div.imag = 0.0;
331 mod = c_diff(v->cval, c_prod(w->cval, div));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000332 d = PyComplex_FromCComplex(div);
333 m = PyComplex_FromCComplex(mod);
334 z = Py_BuildValue("(OO)", d, m);
Guido van Rossum3be12e91996-09-12 20:56:18 +0000335 Py_XDECREF(d);
336 Py_XDECREF(m);
337 return z;
338}
Guido van Rossumf9fca921996-01-12 00:47:05 +0000339
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000340static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000341complex_pow(PyComplexObject *v, PyObject *w, PyComplexObject *z)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000342{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000343 Py_complex p;
344 Py_complex exponent;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000345 long int_exponent;
346
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000347 if ((PyObject *)z!=Py_None) {
348 PyErr_SetString(PyExc_ValueError, "complex modulo");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000349 return NULL;
350 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000351 PyFPE_START_PROTECT("complex_pow", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000352 errno = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000353 exponent = ((PyComplexObject*)w)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000354 int_exponent = (long)exponent.real;
355 if (exponent.imag == 0. && exponent.real == int_exponent)
356 p = c_powi(v->cval,int_exponent);
357 else
358 p = c_pow(v->cval,exponent);
359
Guido van Rossum45b83911997-03-14 04:32:50 +0000360 PyFPE_END_PROTECT(p)
Guido van Rossum96783941997-05-20 18:21:34 +0000361 if (errno == ERANGE) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000362 PyErr_SetString(PyExc_ValueError,
363 "0.0 to a negative or complex power");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000364 return NULL;
365 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000366 return PyComplex_FromCComplex(p);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000367}
368
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000369static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000370complex_neg(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000371{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000372 Py_complex neg;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000373 neg.real = -v->cval.real;
374 neg.imag = -v->cval.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000375 return PyComplex_FromCComplex(neg);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000376}
377
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000378static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000379complex_pos(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000380{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000381 Py_INCREF(v);
382 return (PyObject *)v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000383}
384
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000385static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000386complex_abs(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000387{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000388 double result;
389 PyFPE_START_PROTECT("complex_abs", return 0)
390 result = hypot(v->cval.real,v->cval.imag);
Guido van Rossum45b83911997-03-14 04:32:50 +0000391 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000392 return PyFloat_FromDouble(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000393}
394
395static int
Fred Drake4288c802000-07-09 04:36:04 +0000396complex_nonzero(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000397{
Guido van Rossum3bbef601999-01-25 19:42:19 +0000398 return v->cval.real != 0.0 || v->cval.imag != 0.0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000399}
400
401static int
Fred Drake4288c802000-07-09 04:36:04 +0000402complex_coerce(PyObject **pv, PyObject **pw)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000403{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000404 Py_complex cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000405 cval.imag = 0.;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000406 if (PyInt_Check(*pw)) {
407 cval.real = (double)PyInt_AsLong(*pw);
408 *pw = PyComplex_FromCComplex(cval);
409 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000410 return 0;
411 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000412 else if (PyLong_Check(*pw)) {
413 cval.real = PyLong_AsDouble(*pw);
414 *pw = PyComplex_FromCComplex(cval);
415 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000416 return 0;
417 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000418 else if (PyFloat_Check(*pw)) {
419 cval.real = PyFloat_AsDouble(*pw);
420 *pw = PyComplex_FromCComplex(cval);
421 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000422 return 0;
423 }
424 return 1; /* Can't do it */
425}
426
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000427static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000428complex_int(PyObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000429{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000430 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000431 "can't convert complex to int; use e.g. int(abs(z))");
432 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000433}
434
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000435static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000436complex_long(PyObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000437{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000438 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000439 "can't convert complex to long; use e.g. long(abs(z))");
440 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000441}
442
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000443static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000444complex_float(PyObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000445{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000446 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000447 "can't convert complex to float; use e.g. abs(z)");
448 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000449}
450
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000451static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000452complex_conjugate(PyObject *self, PyObject *args)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000453{
Guido van Rossum926518b1996-08-19 19:30:45 +0000454 Py_complex c;
Guido van Rossum43713e52000-02-29 13:59:29 +0000455 if (!PyArg_ParseTuple(args, ":conjugate"))
Guido van Rossum8530ef61998-05-07 16:29:10 +0000456 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000457 c = ((PyComplexObject *)self)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000458 c.imag = -c.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000459 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000460}
461
462static PyMethodDef complex_methods[] = {
Guido van Rossum8530ef61998-05-07 16:29:10 +0000463 {"conjugate", complex_conjugate, 1},
Guido van Rossumf9fca921996-01-12 00:47:05 +0000464 {NULL, NULL} /* sentinel */
465};
466
467
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000468static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000469complex_getattr(PyComplexObject *self, char *name)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000470{
Guido van Rossumf9fca921996-01-12 00:47:05 +0000471 if (strcmp(name, "real") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000472 return (PyObject *)PyFloat_FromDouble(self->cval.real);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000473 else if (strcmp(name, "imag") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000474 return (PyObject *)PyFloat_FromDouble(self->cval.imag);
Guido van Rossumc054d701997-04-01 03:12:33 +0000475 else if (strcmp(name, "__members__") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000476 return Py_BuildValue("[ss]", "imag", "real");
477 return Py_FindMethod(complex_methods, (PyObject *)self, name);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000478}
479
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000480static PyNumberMethods complex_as_number = {
Guido van Rossumf9fca921996-01-12 00:47:05 +0000481 (binaryfunc)complex_add, /*nb_add*/
482 (binaryfunc)complex_sub, /*nb_subtract*/
483 (binaryfunc)complex_mul, /*nb_multiply*/
484 (binaryfunc)complex_div, /*nb_divide*/
Guido van Rossumee09fc11996-09-11 13:55:55 +0000485 (binaryfunc)complex_remainder, /*nb_remainder*/
486 (binaryfunc)complex_divmod, /*nb_divmod*/
Guido van Rossumf9fca921996-01-12 00:47:05 +0000487 (ternaryfunc)complex_pow, /*nb_power*/
488 (unaryfunc)complex_neg, /*nb_negative*/
489 (unaryfunc)complex_pos, /*nb_positive*/
490 (unaryfunc)complex_abs, /*nb_absolute*/
491 (inquiry)complex_nonzero, /*nb_nonzero*/
492 0, /*nb_invert*/
493 0, /*nb_lshift*/
494 0, /*nb_rshift*/
495 0, /*nb_and*/
496 0, /*nb_xor*/
497 0, /*nb_or*/
498 (coercion)complex_coerce, /*nb_coerce*/
499 (unaryfunc)complex_int, /*nb_int*/
500 (unaryfunc)complex_long, /*nb_long*/
501 (unaryfunc)complex_float, /*nb_float*/
502 0, /*nb_oct*/
503 0, /*nb_hex*/
504};
505
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000506PyTypeObject PyComplex_Type = {
507 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000508 0,
509 "complex",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000510 sizeof(PyComplexObject),
Guido van Rossumf9fca921996-01-12 00:47:05 +0000511 0,
512 (destructor)complex_dealloc, /*tp_dealloc*/
513 (printfunc)complex_print, /*tp_print*/
514 (getattrfunc)complex_getattr, /*tp_getattr*/
515 0, /*tp_setattr*/
516 (cmpfunc)complex_compare, /*tp_compare*/
517 (reprfunc)complex_repr, /*tp_repr*/
518 &complex_as_number, /*tp_as_number*/
519 0, /*tp_as_sequence*/
520 0, /*tp_as_mapping*/
521 (hashfunc)complex_hash, /*tp_hash*/
522};
523
524#endif