blob: 3c1301c7a0c175d2ae4c928d44f61357e37ee36b [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
Tim Peters70695122001-03-11 08:37:29 +000012/* Precisions used by repr() and str(), respectively.
13
14 The repr() precision (17 significant decimal digits) is the minimal number
15 that is guaranteed to have enough precision so that if the number is read
16 back in the exact same binary value is recreated. This is true for IEEE
17 floating point by design, and also happens to work for all other modern
18 hardware.
19
20 The str() precision is chosen so that in most cases, the rounding noise
21 created by various operations is suppressed, while giving plenty of
22 precision for practical use.
23*/
24
25#define PREC_REPR 17
26#define PREC_STR 12
Guido van Rossumf9fca921996-01-12 00:47:05 +000027
28/* elementary operations on complex numbers */
29
Guido van Rossum9e720e31996-07-21 02:31:35 +000030static Py_complex c_1 = {1., 0.};
Guido van Rossumf9fca921996-01-12 00:47:05 +000031
Fred Drake4288c802000-07-09 04:36:04 +000032Py_complex c_sum(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +000033{
Guido van Rossum9e720e31996-07-21 02:31:35 +000034 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000035 r.real = a.real + b.real;
36 r.imag = a.imag + b.imag;
37 return r;
38}
39
Fred Drake4288c802000-07-09 04:36:04 +000040Py_complex c_diff(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +000041{
Guido van Rossum9e720e31996-07-21 02:31:35 +000042 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000043 r.real = a.real - b.real;
44 r.imag = a.imag - b.imag;
45 return r;
46}
47
Fred Drake4288c802000-07-09 04:36:04 +000048Py_complex c_neg(Py_complex a)
Guido van Rossumf9fca921996-01-12 00:47:05 +000049{
Guido van Rossum9e720e31996-07-21 02:31:35 +000050 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000051 r.real = -a.real;
52 r.imag = -a.imag;
53 return r;
54}
55
Fred Drake4288c802000-07-09 04:36:04 +000056Py_complex c_prod(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +000057{
Guido van Rossum9e720e31996-07-21 02:31:35 +000058 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000059 r.real = a.real*b.real - a.imag*b.imag;
60 r.imag = a.real*b.imag + a.imag*b.real;
61 return r;
62}
63
Fred Drake4288c802000-07-09 04:36:04 +000064Py_complex c_quot(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 d = b.real*b.real + b.imag*b.imag;
68 if (d == 0.)
Guido van Rossum96783941997-05-20 18:21:34 +000069 errno = EDOM;
Guido van Rossumf9fca921996-01-12 00:47:05 +000070 r.real = (a.real*b.real + a.imag*b.imag)/d;
71 r.imag = (a.imag*b.real - a.real*b.imag)/d;
72 return r;
73}
74
Fred Drake4288c802000-07-09 04:36:04 +000075Py_complex c_pow(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +000076{
Guido van Rossum9e720e31996-07-21 02:31:35 +000077 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000078 double vabs,len,at,phase;
79 if (b.real == 0. && b.imag == 0.) {
80 r.real = 1.;
81 r.imag = 0.;
82 }
83 else if (a.real == 0. && a.imag == 0.) {
84 if (b.imag != 0. || b.real < 0.)
Guido van Rossum96783941997-05-20 18:21:34 +000085 errno = ERANGE;
Guido van Rossumf9fca921996-01-12 00:47:05 +000086 r.real = 0.;
87 r.imag = 0.;
88 }
89 else {
90 vabs = hypot(a.real,a.imag);
91 len = pow(vabs,b.real);
92 at = atan2(a.imag, a.real);
93 phase = at*b.real;
94 if (b.imag != 0.0) {
95 len /= exp(at*b.imag);
96 phase += b.imag*log(vabs);
97 }
98 r.real = len*cos(phase);
99 r.imag = len*sin(phase);
100 }
101 return r;
102}
103
Fred Drake4288c802000-07-09 04:36:04 +0000104static Py_complex c_powu(Py_complex x, long n)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000105{
Guido van Rossum926518b1996-08-19 19:30:45 +0000106 Py_complex r, p;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000107 long mask = 1;
Guido van Rossum926518b1996-08-19 19:30:45 +0000108 r = c_1;
109 p = x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000110 while (mask > 0 && n >= mask) {
111 if (n & mask)
112 r = c_prod(r,p);
113 mask <<= 1;
114 p = c_prod(p,p);
115 }
116 return r;
117}
118
Fred Drake4288c802000-07-09 04:36:04 +0000119static Py_complex c_powi(Py_complex x, long n)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000120{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000121 Py_complex cn;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000122
123 if (n > 100 || n < -100) {
124 cn.real = (double) n;
125 cn.imag = 0.;
126 return c_pow(x,cn);
127 }
128 else if (n > 0)
129 return c_powu(x,n);
130 else
131 return c_quot(c_1,c_powu(x,-n));
132
133}
134
135PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000136PyComplex_FromCComplex(Py_complex cval)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000137{
Guido van Rossumb18618d2000-05-03 23:44:39 +0000138 register PyComplexObject *op;
139
140 /* PyObject_New is inlined */
141 op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject));
Guido van Rossumf9fca921996-01-12 00:47:05 +0000142 if (op == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000143 return PyErr_NoMemory();
Guido van Rossumb18618d2000-05-03 23:44:39 +0000144 PyObject_INIT(op, &PyComplex_Type);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000145 op->cval = cval;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000146 return (PyObject *) op;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000147}
148
149PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000150PyComplex_FromDoubles(double real, double imag)
Guido van Rossum926518b1996-08-19 19:30:45 +0000151{
152 Py_complex c;
153 c.real = real;
154 c.imag = imag;
155 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000156}
157
158double
Fred Drake4288c802000-07-09 04:36:04 +0000159PyComplex_RealAsDouble(PyObject *op)
Guido van Rossum926518b1996-08-19 19:30:45 +0000160{
161 if (PyComplex_Check(op)) {
162 return ((PyComplexObject *)op)->cval.real;
Fred Drake4288c802000-07-09 04:36:04 +0000163 }
164 else {
Guido van Rossum926518b1996-08-19 19:30:45 +0000165 return PyFloat_AsDouble(op);
166 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000167}
168
169double
Fred Drake4288c802000-07-09 04:36:04 +0000170PyComplex_ImagAsDouble(PyObject *op)
Guido van Rossum926518b1996-08-19 19:30:45 +0000171{
172 if (PyComplex_Check(op)) {
173 return ((PyComplexObject *)op)->cval.imag;
Fred Drake4288c802000-07-09 04:36:04 +0000174 }
175 else {
Guido van Rossum926518b1996-08-19 19:30:45 +0000176 return 0.0;
177 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000178}
179
Guido van Rossum9e720e31996-07-21 02:31:35 +0000180Py_complex
Fred Drake4288c802000-07-09 04:36:04 +0000181PyComplex_AsCComplex(PyObject *op)
Guido van Rossum926518b1996-08-19 19:30:45 +0000182{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000183 Py_complex cv;
Guido van Rossumcf3d1081996-01-12 01:21:14 +0000184 if (PyComplex_Check(op)) {
185 return ((PyComplexObject *)op)->cval;
Fred Drake4288c802000-07-09 04:36:04 +0000186 }
187 else {
Guido van Rossumcf3d1081996-01-12 01:21:14 +0000188 cv.real = PyFloat_AsDouble(op);
189 cv.imag = 0.;
190 return cv;
Tim Peters70695122001-03-11 08:37:29 +0000191 }
Guido van Rossumcf3d1081996-01-12 01:21:14 +0000192}
193
Guido van Rossumf9fca921996-01-12 00:47:05 +0000194static void
Fred Drake4288c802000-07-09 04:36:04 +0000195complex_dealloc(PyObject *op)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000196{
Guido van Rossumb18618d2000-05-03 23:44:39 +0000197 PyObject_DEL(op);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000198}
199
200
Guido van Rossum363078a1996-05-24 20:45:01 +0000201static void
Tim Peters70695122001-03-11 08:37:29 +0000202complex_to_buf(char *buf, PyComplexObject *v, int precision)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000203{
204 if (v->cval.real == 0.)
Tim Peters70695122001-03-11 08:37:29 +0000205 sprintf(buf, "%.*gj", precision, v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000206 else
Tim Peters70695122001-03-11 08:37:29 +0000207 sprintf(buf, "(%.*g%+.*gj)", precision, v->cval.real,
208 precision, v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000209}
210
211static int
Fred Drake4288c802000-07-09 04:36:04 +0000212complex_print(PyComplexObject *v, FILE *fp, int flags)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000213{
214 char buf[100];
Tim Peters70695122001-03-11 08:37:29 +0000215 complex_to_buf(buf, v,
216 (flags & Py_PRINT_RAW) ? PREC_STR : PREC_REPR);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000217 fputs(buf, fp);
218 return 0;
219}
220
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000221static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000222complex_repr(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000223{
224 char buf[100];
Tim Peters70695122001-03-11 08:37:29 +0000225 complex_to_buf(buf, v, PREC_REPR);
226 return PyString_FromString(buf);
227}
228
229static PyObject *
230complex_str(PyComplexObject *v)
231{
232 char buf[100];
233 complex_to_buf(buf, v, PREC_STR);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000234 return PyString_FromString(buf);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000235}
236
Guido van Rossumf9fca921996-01-12 00:47:05 +0000237static long
Fred Drake4288c802000-07-09 04:36:04 +0000238complex_hash(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000239{
Tim Peters39dce292000-08-15 03:34:48 +0000240 long hashreal, hashimag, combined;
241 hashreal = _Py_HashDouble(v->cval.real);
242 if (hashreal == -1)
243 return -1;
244 hashimag = _Py_HashDouble(v->cval.imag);
245 if (hashimag == -1)
246 return -1;
247 /* Note: if the imaginary part is 0, hashimag is 0 now,
248 * so the following returns hashreal unchanged. This is
249 * important because numbers of different types that
250 * compare equal must have the same hash value, so that
251 * hash(x + 0*j) must equal hash(x).
252 */
253 combined = hashreal + 1000003 * hashimag;
254 if (combined == -1)
255 combined = -2;
256 return combined;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000257}
258
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000259static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000260complex_add(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000261{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000262 Py_complex result;
263 PyFPE_START_PROTECT("complex_add", return 0)
264 result = c_sum(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000265 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000266 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000267}
268
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000269static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000270complex_sub(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000271{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000272 Py_complex result;
273 PyFPE_START_PROTECT("complex_sub", return 0)
274 result = c_diff(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000275 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000276 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000277}
278
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000279static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000280complex_mul(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000281{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000282 Py_complex result;
283 PyFPE_START_PROTECT("complex_mul", return 0)
284 result = c_prod(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000285 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000286 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000287}
288
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000289static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000290complex_div(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000291{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000292 Py_complex quot;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000293 PyFPE_START_PROTECT("complex_div", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000294 errno = 0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000295 quot = c_quot(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000296 PyFPE_END_PROTECT(quot)
Guido van Rossum96783941997-05-20 18:21:34 +0000297 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000298 PyErr_SetString(PyExc_ZeroDivisionError, "complex division");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000299 return NULL;
300 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000301 return PyComplex_FromCComplex(quot);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000302}
303
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000304static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000305complex_remainder(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumee09fc11996-09-11 13:55:55 +0000306{
Guido van Rossum3be12e91996-09-12 20:56:18 +0000307 Py_complex div, mod;
Guido van Rossum96783941997-05-20 18:21:34 +0000308 errno = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000309 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
Guido van Rossum96783941997-05-20 18:21:34 +0000310 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000311 PyErr_SetString(PyExc_ZeroDivisionError, "complex remainder");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000312 return NULL;
313 }
314 div.real = floor(div.real); /* Use the floor of the real part. */
315 div.imag = 0.0;
316 mod = c_diff(v->cval, c_prod(w->cval, div));
317
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000318 return PyComplex_FromCComplex(mod);
Guido van Rossumee09fc11996-09-11 13:55:55 +0000319}
320
Guido van Rossumee09fc11996-09-11 13:55:55 +0000321
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000322static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000323complex_divmod(PyComplexObject *v, PyComplexObject *w)
Guido van Rossum3be12e91996-09-12 20:56:18 +0000324{
325 Py_complex div, mod;
326 PyObject *d, *m, *z;
Guido van Rossum96783941997-05-20 18:21:34 +0000327 errno = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000328 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
Guido van Rossum96783941997-05-20 18:21:34 +0000329 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000330 PyErr_SetString(PyExc_ZeroDivisionError, "complex divmod()");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000331 return NULL;
332 }
333 div.real = floor(div.real); /* Use the floor of the real part. */
334 div.imag = 0.0;
335 mod = c_diff(v->cval, c_prod(w->cval, div));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000336 d = PyComplex_FromCComplex(div);
337 m = PyComplex_FromCComplex(mod);
338 z = Py_BuildValue("(OO)", d, m);
Guido van Rossum3be12e91996-09-12 20:56:18 +0000339 Py_XDECREF(d);
340 Py_XDECREF(m);
341 return z;
342}
Guido van Rossumf9fca921996-01-12 00:47:05 +0000343
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000344static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000345complex_pow(PyComplexObject *v, PyObject *w, PyComplexObject *z)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000346{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000347 Py_complex p;
348 Py_complex exponent;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000349 long int_exponent;
350
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000351 if ((PyObject *)z!=Py_None) {
352 PyErr_SetString(PyExc_ValueError, "complex modulo");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000353 return NULL;
354 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000355 PyFPE_START_PROTECT("complex_pow", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000356 errno = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000357 exponent = ((PyComplexObject*)w)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000358 int_exponent = (long)exponent.real;
359 if (exponent.imag == 0. && exponent.real == int_exponent)
360 p = c_powi(v->cval,int_exponent);
361 else
362 p = c_pow(v->cval,exponent);
363
Guido van Rossum45b83911997-03-14 04:32:50 +0000364 PyFPE_END_PROTECT(p)
Guido van Rossum96783941997-05-20 18:21:34 +0000365 if (errno == ERANGE) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000366 PyErr_SetString(PyExc_ValueError,
367 "0.0 to a negative or complex power");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000368 return NULL;
369 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000370 return PyComplex_FromCComplex(p);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000371}
372
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000373static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000374complex_neg(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000375{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000376 Py_complex neg;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000377 neg.real = -v->cval.real;
378 neg.imag = -v->cval.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000379 return PyComplex_FromCComplex(neg);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000380}
381
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000382static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000383complex_pos(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000384{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000385 Py_INCREF(v);
386 return (PyObject *)v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000387}
388
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000389static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000390complex_abs(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000391{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000392 double result;
393 PyFPE_START_PROTECT("complex_abs", return 0)
394 result = hypot(v->cval.real,v->cval.imag);
Guido van Rossum45b83911997-03-14 04:32:50 +0000395 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000396 return PyFloat_FromDouble(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000397}
398
399static int
Fred Drake4288c802000-07-09 04:36:04 +0000400complex_nonzero(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000401{
Guido van Rossum3bbef601999-01-25 19:42:19 +0000402 return v->cval.real != 0.0 || v->cval.imag != 0.0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000403}
404
405static int
Fred Drake4288c802000-07-09 04:36:04 +0000406complex_coerce(PyObject **pv, PyObject **pw)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000407{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000408 Py_complex cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000409 cval.imag = 0.;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000410 if (PyInt_Check(*pw)) {
411 cval.real = (double)PyInt_AsLong(*pw);
412 *pw = PyComplex_FromCComplex(cval);
413 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000414 return 0;
415 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000416 else if (PyLong_Check(*pw)) {
417 cval.real = PyLong_AsDouble(*pw);
418 *pw = PyComplex_FromCComplex(cval);
419 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000420 return 0;
421 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000422 else if (PyFloat_Check(*pw)) {
423 cval.real = PyFloat_AsDouble(*pw);
424 *pw = PyComplex_FromCComplex(cval);
425 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000426 return 0;
427 }
428 return 1; /* Can't do it */
429}
430
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000431static PyObject *
Guido van Rossumbe4cbb12001-01-18 01:12:39 +0000432complex_richcompare(PyObject *v, PyObject *w, int op)
433{
434 int c;
435 Py_complex i, j;
436 PyObject *res;
437
438 if (op != Py_EQ && op != Py_NE) {
439 PyErr_SetString(PyExc_TypeError,
440 "cannot compare complex numbers using <, <=, >, >=");
441 return NULL;
442 }
443
444 c = PyNumber_CoerceEx(&v, &w);
445 if (c < 0)
446 return NULL;
447 if (c > 0) {
448 Py_INCREF(Py_NotImplemented);
449 return Py_NotImplemented;
450 }
451 if (!PyComplex_Check(v) || !PyComplex_Check(w)) {
452 Py_DECREF(v);
453 Py_DECREF(w);
454 Py_INCREF(Py_NotImplemented);
455 return Py_NotImplemented;
456 }
457
458 i = ((PyComplexObject *)v)->cval;
459 j = ((PyComplexObject *)w)->cval;
460 Py_DECREF(v);
461 Py_DECREF(w);
462
463 if ((i.real == j.real && i.imag == j.imag) == (op == Py_EQ))
464 res = Py_True;
465 else
466 res = Py_False;
467
468 Py_INCREF(res);
469 return res;
470}
471
472static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000473complex_int(PyObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000474{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000475 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000476 "can't convert complex to int; use e.g. int(abs(z))");
477 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000478}
479
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000480static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000481complex_long(PyObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000482{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000483 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000484 "can't convert complex to long; use e.g. long(abs(z))");
485 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000486}
487
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000488static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000489complex_float(PyObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000490{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000491 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000492 "can't convert complex to float; use e.g. abs(z)");
493 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000494}
495
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000496static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000497complex_conjugate(PyObject *self, PyObject *args)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000498{
Guido van Rossum926518b1996-08-19 19:30:45 +0000499 Py_complex c;
Guido van Rossum43713e52000-02-29 13:59:29 +0000500 if (!PyArg_ParseTuple(args, ":conjugate"))
Guido van Rossum8530ef61998-05-07 16:29:10 +0000501 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000502 c = ((PyComplexObject *)self)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000503 c.imag = -c.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000504 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000505}
506
507static PyMethodDef complex_methods[] = {
Guido van Rossum8530ef61998-05-07 16:29:10 +0000508 {"conjugate", complex_conjugate, 1},
Guido van Rossumf9fca921996-01-12 00:47:05 +0000509 {NULL, NULL} /* sentinel */
510};
511
512
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000513static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000514complex_getattr(PyComplexObject *self, char *name)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000515{
Guido van Rossumf9fca921996-01-12 00:47:05 +0000516 if (strcmp(name, "real") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000517 return (PyObject *)PyFloat_FromDouble(self->cval.real);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000518 else if (strcmp(name, "imag") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000519 return (PyObject *)PyFloat_FromDouble(self->cval.imag);
Guido van Rossumc054d701997-04-01 03:12:33 +0000520 else if (strcmp(name, "__members__") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000521 return Py_BuildValue("[ss]", "imag", "real");
522 return Py_FindMethod(complex_methods, (PyObject *)self, name);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000523}
524
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000525static PyNumberMethods complex_as_number = {
Guido van Rossumbe4cbb12001-01-18 01:12:39 +0000526 (binaryfunc)complex_add, /* nb_add */
527 (binaryfunc)complex_sub, /* nb_subtract */
528 (binaryfunc)complex_mul, /* nb_multiply */
529 (binaryfunc)complex_div, /* nb_divide */
530 (binaryfunc)complex_remainder, /* nb_remainder */
531 (binaryfunc)complex_divmod, /* nb_divmod */
532 (ternaryfunc)complex_pow, /* nb_power */
533 (unaryfunc)complex_neg, /* nb_negative */
534 (unaryfunc)complex_pos, /* nb_positive */
535 (unaryfunc)complex_abs, /* nb_absolute */
536 (inquiry)complex_nonzero, /* nb_nonzero */
537 0, /* nb_invert */
538 0, /* nb_lshift */
539 0, /* nb_rshift */
540 0, /* nb_and */
541 0, /* nb_xor */
542 0, /* nb_or */
543 (coercion)complex_coerce, /* nb_coerce */
544 (unaryfunc)complex_int, /* nb_int */
545 (unaryfunc)complex_long, /* nb_long */
546 (unaryfunc)complex_float, /* nb_float */
547 0, /* nb_oct */
548 0, /* nb_hex */
Guido van Rossumf9fca921996-01-12 00:47:05 +0000549};
550
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000551PyTypeObject PyComplex_Type = {
552 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000553 0,
554 "complex",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000555 sizeof(PyComplexObject),
Guido van Rossumf9fca921996-01-12 00:47:05 +0000556 0,
Guido van Rossumbe4cbb12001-01-18 01:12:39 +0000557 (destructor)complex_dealloc, /* tp_dealloc */
558 (printfunc)complex_print, /* tp_print */
559 (getattrfunc)complex_getattr, /* tp_getattr */
560 0, /* tp_setattr */
561 0, /* tp_compare */
562 (reprfunc)complex_repr, /* tp_repr */
563 &complex_as_number, /* tp_as_number */
564 0, /* tp_as_sequence */
565 0, /* tp_as_mapping */
566 (hashfunc)complex_hash, /* tp_hash */
567 0, /* tp_call */
Tim Peters70695122001-03-11 08:37:29 +0000568 (reprfunc)complex_str, /* tp_str */
Guido van Rossumbe4cbb12001-01-18 01:12:39 +0000569 0, /* tp_getattro */
570 0, /* tp_setattro */
571 0, /* tp_as_buffer */
572 Py_TPFLAGS_DEFAULT, /* tp_flags */
573 0, /* tp_doc */
574 0, /* tp_traverse */
575 0, /* tp_clear */
576 complex_richcompare, /* tp_richcompare */
Guido van Rossumf9fca921996-01-12 00:47:05 +0000577};
578
579#endif