blob: 740499319a9fef3b754eb5332adde7bf63afd9ae [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"
Tim Peters6d6c1a32001-08-02 04:15:00 +000011#include "structmember.h"
Guido van Rossumf9fca921996-01-12 00:47:05 +000012
Tim Peters70695122001-03-11 08:37:29 +000013/* Precisions used by repr() and str(), respectively.
14
15 The repr() precision (17 significant decimal digits) is the minimal number
16 that is guaranteed to have enough precision so that if the number is read
17 back in the exact same binary value is recreated. This is true for IEEE
18 floating point by design, and also happens to work for all other modern
19 hardware.
20
21 The str() precision is chosen so that in most cases, the rounding noise
22 created by various operations is suppressed, while giving plenty of
23 precision for practical use.
24*/
25
26#define PREC_REPR 17
27#define PREC_STR 12
Guido van Rossumf9fca921996-01-12 00:47:05 +000028
29/* elementary operations on complex numbers */
30
Guido van Rossum9e720e31996-07-21 02:31:35 +000031static Py_complex c_1 = {1., 0.};
Guido van Rossumf9fca921996-01-12 00:47:05 +000032
Tim Peters0f336042001-03-18 08:21:57 +000033Py_complex
34c_sum(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +000035{
Guido van Rossum9e720e31996-07-21 02:31:35 +000036 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000037 r.real = a.real + b.real;
38 r.imag = a.imag + b.imag;
39 return r;
40}
41
Tim Peters0f336042001-03-18 08:21:57 +000042Py_complex
43c_diff(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +000044{
Guido van Rossum9e720e31996-07-21 02:31:35 +000045 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000046 r.real = a.real - b.real;
47 r.imag = a.imag - b.imag;
48 return r;
49}
50
Tim Peters0f336042001-03-18 08:21:57 +000051Py_complex
52c_neg(Py_complex a)
Guido van Rossumf9fca921996-01-12 00:47:05 +000053{
Guido van Rossum9e720e31996-07-21 02:31:35 +000054 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000055 r.real = -a.real;
56 r.imag = -a.imag;
57 return r;
58}
59
Tim Peters0f336042001-03-18 08:21:57 +000060Py_complex
61c_prod(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +000062{
Guido van Rossum9e720e31996-07-21 02:31:35 +000063 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000064 r.real = a.real*b.real - a.imag*b.imag;
65 r.imag = a.real*b.imag + a.imag*b.real;
66 return r;
67}
68
Tim Peters0f336042001-03-18 08:21:57 +000069Py_complex
70c_quot(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +000071{
Tim Peters0f336042001-03-18 08:21:57 +000072 /******************************************************************
73 This was the original algorithm. It's grossly prone to spurious
74 overflow and underflow errors. It also merrily divides by 0 despite
75 checking for that(!). The code still serves a doc purpose here, as
76 the algorithm following is a simple by-cases transformation of this
77 one:
78
Guido van Rossum9e720e31996-07-21 02:31:35 +000079 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000080 double d = b.real*b.real + b.imag*b.imag;
81 if (d == 0.)
Guido van Rossum96783941997-05-20 18:21:34 +000082 errno = EDOM;
Guido van Rossumf9fca921996-01-12 00:47:05 +000083 r.real = (a.real*b.real + a.imag*b.imag)/d;
84 r.imag = (a.imag*b.real - a.real*b.imag)/d;
85 return r;
Tim Peters0f336042001-03-18 08:21:57 +000086 ******************************************************************/
87
88 /* This algorithm is better, and is pretty obvious: first divide the
89 * numerators and denominator by whichever of {b.real, b.imag} has
90 * larger magnitude. The earliest reference I found was to CACM
91 * Algorithm 116 (Complex Division, Robert L. Smith, Stanford
92 * University). As usual, though, we're still ignoring all IEEE
93 * endcases.
94 */
95 Py_complex r; /* the result */
96 const double abs_breal = b.real < 0 ? -b.real : b.real;
97 const double abs_bimag = b.imag < 0 ? -b.imag : b.imag;
98
99 if (abs_breal >= abs_bimag) {
100 /* divide tops and bottom by b.real */
101 if (abs_breal == 0.0) {
102 errno = EDOM;
103 r.real = r.imag = 0.0;
104 }
105 else {
106 const double ratio = b.imag / b.real;
107 const double denom = b.real + b.imag * ratio;
108 r.real = (a.real + a.imag * ratio) / denom;
109 r.imag = (a.imag - a.real * ratio) / denom;
110 }
111 }
112 else {
113 /* divide tops and bottom by b.imag */
114 const double ratio = b.real / b.imag;
115 const double denom = b.real * ratio + b.imag;
116 assert(b.imag != 0.0);
117 r.real = (a.real * ratio + a.imag) / denom;
118 r.imag = (a.imag * ratio - a.real) / denom;
119 }
120 return r;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000121}
122
Tim Peters0f336042001-03-18 08:21:57 +0000123Py_complex
124c_pow(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000125{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000126 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000127 double vabs,len,at,phase;
128 if (b.real == 0. && b.imag == 0.) {
129 r.real = 1.;
130 r.imag = 0.;
131 }
132 else if (a.real == 0. && a.imag == 0.) {
133 if (b.imag != 0. || b.real < 0.)
Guido van Rossum96783941997-05-20 18:21:34 +0000134 errno = ERANGE;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000135 r.real = 0.;
136 r.imag = 0.;
137 }
138 else {
139 vabs = hypot(a.real,a.imag);
140 len = pow(vabs,b.real);
Martin v. Löwis387c5472001-09-06 08:16:17 +0000141 at = atan2(a.imag, a.real);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000142 phase = at*b.real;
143 if (b.imag != 0.0) {
144 len /= exp(at*b.imag);
145 phase += b.imag*log(vabs);
146 }
147 r.real = len*cos(phase);
148 r.imag = len*sin(phase);
149 }
150 return r;
151}
152
Tim Peters0f336042001-03-18 08:21:57 +0000153static Py_complex
154c_powu(Py_complex x, long n)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000155{
Guido van Rossum926518b1996-08-19 19:30:45 +0000156 Py_complex r, p;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000157 long mask = 1;
Guido van Rossum926518b1996-08-19 19:30:45 +0000158 r = c_1;
159 p = x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000160 while (mask > 0 && n >= mask) {
161 if (n & mask)
162 r = c_prod(r,p);
163 mask <<= 1;
164 p = c_prod(p,p);
165 }
166 return r;
167}
168
Tim Peters0f336042001-03-18 08:21:57 +0000169static Py_complex
170c_powi(Py_complex x, long n)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000171{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000172 Py_complex cn;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000173
174 if (n > 100 || n < -100) {
175 cn.real = (double) n;
176 cn.imag = 0.;
177 return c_pow(x,cn);
178 }
179 else if (n > 0)
180 return c_powu(x,n);
181 else
182 return c_quot(c_1,c_powu(x,-n));
183
184}
185
Tim Peters6d6c1a32001-08-02 04:15:00 +0000186static PyObject *
187complex_subtype_from_c_complex(PyTypeObject *type, Py_complex cval)
188{
189 PyObject *op;
190
191 op = PyType_GenericAlloc(type, 0);
192 if (op != NULL)
193 ((PyComplexObject *)op)->cval = cval;
194 return op;
195}
196
Guido van Rossumf9fca921996-01-12 00:47:05 +0000197PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000198PyComplex_FromCComplex(Py_complex cval)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000199{
Guido van Rossumb18618d2000-05-03 23:44:39 +0000200 register PyComplexObject *op;
201
202 /* PyObject_New is inlined */
203 op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject));
Guido van Rossumf9fca921996-01-12 00:47:05 +0000204 if (op == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000205 return PyErr_NoMemory();
Guido van Rossumb18618d2000-05-03 23:44:39 +0000206 PyObject_INIT(op, &PyComplex_Type);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000207 op->cval = cval;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000208 return (PyObject *) op;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000209}
210
Tim Peters6d6c1a32001-08-02 04:15:00 +0000211static PyObject *
212complex_subtype_from_doubles(PyTypeObject *type, double real, double imag)
213{
214 Py_complex c;
215 c.real = real;
216 c.imag = imag;
217 return complex_subtype_from_c_complex(type, c);
218}
219
Guido van Rossumf9fca921996-01-12 00:47:05 +0000220PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000221PyComplex_FromDoubles(double real, double imag)
Guido van Rossum926518b1996-08-19 19:30:45 +0000222{
223 Py_complex c;
224 c.real = real;
225 c.imag = imag;
226 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000227}
228
229double
Fred Drake4288c802000-07-09 04:36:04 +0000230PyComplex_RealAsDouble(PyObject *op)
Guido van Rossum926518b1996-08-19 19:30:45 +0000231{
232 if (PyComplex_Check(op)) {
233 return ((PyComplexObject *)op)->cval.real;
Fred Drake4288c802000-07-09 04:36:04 +0000234 }
235 else {
Guido van Rossum926518b1996-08-19 19:30:45 +0000236 return PyFloat_AsDouble(op);
237 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000238}
239
240double
Fred Drake4288c802000-07-09 04:36:04 +0000241PyComplex_ImagAsDouble(PyObject *op)
Guido van Rossum926518b1996-08-19 19:30:45 +0000242{
243 if (PyComplex_Check(op)) {
244 return ((PyComplexObject *)op)->cval.imag;
Fred Drake4288c802000-07-09 04:36:04 +0000245 }
246 else {
Guido van Rossum926518b1996-08-19 19:30:45 +0000247 return 0.0;
248 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000249}
250
Guido van Rossum9e720e31996-07-21 02:31:35 +0000251Py_complex
Fred Drake4288c802000-07-09 04:36:04 +0000252PyComplex_AsCComplex(PyObject *op)
Guido van Rossum926518b1996-08-19 19:30:45 +0000253{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000254 Py_complex cv;
Guido van Rossumcf3d1081996-01-12 01:21:14 +0000255 if (PyComplex_Check(op)) {
256 return ((PyComplexObject *)op)->cval;
Fred Drake4288c802000-07-09 04:36:04 +0000257 }
258 else {
Guido van Rossumcf3d1081996-01-12 01:21:14 +0000259 cv.real = PyFloat_AsDouble(op);
260 cv.imag = 0.;
261 return cv;
Tim Peters70695122001-03-11 08:37:29 +0000262 }
Guido van Rossumcf3d1081996-01-12 01:21:14 +0000263}
264
Guido van Rossumf9fca921996-01-12 00:47:05 +0000265static void
Fred Drake4288c802000-07-09 04:36:04 +0000266complex_dealloc(PyObject *op)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000267{
Guido van Rossumb18618d2000-05-03 23:44:39 +0000268 PyObject_DEL(op);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000269}
270
271
Guido van Rossum363078a1996-05-24 20:45:01 +0000272static void
Tim Peters70695122001-03-11 08:37:29 +0000273complex_to_buf(char *buf, PyComplexObject *v, int precision)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000274{
275 if (v->cval.real == 0.)
Tim Peters70695122001-03-11 08:37:29 +0000276 sprintf(buf, "%.*gj", precision, v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000277 else
Tim Peters70695122001-03-11 08:37:29 +0000278 sprintf(buf, "(%.*g%+.*gj)", precision, v->cval.real,
279 precision, v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000280}
281
282static int
Fred Drake4288c802000-07-09 04:36:04 +0000283complex_print(PyComplexObject *v, FILE *fp, int flags)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000284{
285 char buf[100];
Tim Peters70695122001-03-11 08:37:29 +0000286 complex_to_buf(buf, v,
287 (flags & Py_PRINT_RAW) ? PREC_STR : PREC_REPR);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000288 fputs(buf, fp);
289 return 0;
290}
291
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000292static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000293complex_repr(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000294{
295 char buf[100];
Tim Peters70695122001-03-11 08:37:29 +0000296 complex_to_buf(buf, v, PREC_REPR);
297 return PyString_FromString(buf);
298}
299
300static PyObject *
301complex_str(PyComplexObject *v)
302{
303 char buf[100];
304 complex_to_buf(buf, v, PREC_STR);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000305 return PyString_FromString(buf);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000306}
307
Guido van Rossumf9fca921996-01-12 00:47:05 +0000308static long
Fred Drake4288c802000-07-09 04:36:04 +0000309complex_hash(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000310{
Tim Peters39dce292000-08-15 03:34:48 +0000311 long hashreal, hashimag, combined;
312 hashreal = _Py_HashDouble(v->cval.real);
313 if (hashreal == -1)
314 return -1;
315 hashimag = _Py_HashDouble(v->cval.imag);
316 if (hashimag == -1)
317 return -1;
318 /* Note: if the imaginary part is 0, hashimag is 0 now,
319 * so the following returns hashreal unchanged. This is
320 * important because numbers of different types that
321 * compare equal must have the same hash value, so that
322 * hash(x + 0*j) must equal hash(x).
323 */
324 combined = hashreal + 1000003 * hashimag;
325 if (combined == -1)
326 combined = -2;
327 return combined;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000328}
329
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000330static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000331complex_add(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000332{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000333 Py_complex result;
334 PyFPE_START_PROTECT("complex_add", return 0)
335 result = c_sum(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000336 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000337 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000338}
339
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000340static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000341complex_sub(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000342{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000343 Py_complex result;
344 PyFPE_START_PROTECT("complex_sub", return 0)
345 result = c_diff(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000346 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000347 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000348}
349
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000350static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000351complex_mul(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000352{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000353 Py_complex result;
354 PyFPE_START_PROTECT("complex_mul", return 0)
355 result = c_prod(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000356 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000357 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000358}
359
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000360static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000361complex_div(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000362{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000363 Py_complex quot;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000364 PyFPE_START_PROTECT("complex_div", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000365 errno = 0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000366 quot = c_quot(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000367 PyFPE_END_PROTECT(quot)
Guido van Rossum96783941997-05-20 18:21:34 +0000368 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000369 PyErr_SetString(PyExc_ZeroDivisionError, "complex division");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000370 return NULL;
371 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000372 return PyComplex_FromCComplex(quot);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000373}
374
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000375static PyObject *
Guido van Rossum393661d2001-08-31 17:40:15 +0000376complex_classic_div(PyComplexObject *v, PyComplexObject *w)
377{
378 Py_complex quot;
379
Guido van Rossum1832de42001-09-04 03:51:09 +0000380 if (Py_DivisionWarningFlag >= 2 &&
Guido van Rossum393661d2001-08-31 17:40:15 +0000381 PyErr_Warn(PyExc_DeprecationWarning,
382 "classic complex division") < 0)
383 return NULL;
384
385 PyFPE_START_PROTECT("complex_classic_div", return 0)
386 errno = 0;
387 quot = c_quot(v->cval,w->cval);
388 PyFPE_END_PROTECT(quot)
389 if (errno == EDOM) {
390 PyErr_SetString(PyExc_ZeroDivisionError, "complex division");
391 return NULL;
392 }
393 return PyComplex_FromCComplex(quot);
394}
395
396static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000397complex_remainder(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumee09fc11996-09-11 13:55:55 +0000398{
Guido van Rossum3be12e91996-09-12 20:56:18 +0000399 Py_complex div, mod;
Guido van Rossum96783941997-05-20 18:21:34 +0000400 errno = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000401 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
Guido van Rossum96783941997-05-20 18:21:34 +0000402 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000403 PyErr_SetString(PyExc_ZeroDivisionError, "complex remainder");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000404 return NULL;
405 }
406 div.real = floor(div.real); /* Use the floor of the real part. */
407 div.imag = 0.0;
408 mod = c_diff(v->cval, c_prod(w->cval, div));
409
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000410 return PyComplex_FromCComplex(mod);
Guido van Rossumee09fc11996-09-11 13:55:55 +0000411}
412
Guido van Rossumee09fc11996-09-11 13:55:55 +0000413
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000414static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000415complex_divmod(PyComplexObject *v, PyComplexObject *w)
Guido van Rossum3be12e91996-09-12 20:56:18 +0000416{
417 Py_complex div, mod;
418 PyObject *d, *m, *z;
Guido van Rossum96783941997-05-20 18:21:34 +0000419 errno = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000420 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
Guido van Rossum96783941997-05-20 18:21:34 +0000421 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000422 PyErr_SetString(PyExc_ZeroDivisionError, "complex divmod()");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000423 return NULL;
424 }
425 div.real = floor(div.real); /* Use the floor of the real part. */
426 div.imag = 0.0;
427 mod = c_diff(v->cval, c_prod(w->cval, div));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000428 d = PyComplex_FromCComplex(div);
429 m = PyComplex_FromCComplex(mod);
430 z = Py_BuildValue("(OO)", d, m);
Guido van Rossum3be12e91996-09-12 20:56:18 +0000431 Py_XDECREF(d);
432 Py_XDECREF(m);
433 return z;
434}
Guido van Rossumf9fca921996-01-12 00:47:05 +0000435
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000436static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000437complex_pow(PyComplexObject *v, PyObject *w, PyComplexObject *z)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000438{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000439 Py_complex p;
440 Py_complex exponent;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000441 long int_exponent;
442
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000443 if ((PyObject *)z!=Py_None) {
444 PyErr_SetString(PyExc_ValueError, "complex modulo");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000445 return NULL;
446 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000447 PyFPE_START_PROTECT("complex_pow", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000448 errno = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000449 exponent = ((PyComplexObject*)w)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000450 int_exponent = (long)exponent.real;
451 if (exponent.imag == 0. && exponent.real == int_exponent)
452 p = c_powi(v->cval,int_exponent);
453 else
454 p = c_pow(v->cval,exponent);
455
Guido van Rossum45b83911997-03-14 04:32:50 +0000456 PyFPE_END_PROTECT(p)
Guido van Rossum96783941997-05-20 18:21:34 +0000457 if (errno == ERANGE) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000458 PyErr_SetString(PyExc_ValueError,
459 "0.0 to a negative or complex power");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000460 return NULL;
461 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000462 return PyComplex_FromCComplex(p);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000463}
464
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000465static PyObject *
Guido van Rossum4668b002001-08-08 05:00:18 +0000466complex_int_div(PyComplexObject *v, PyComplexObject *w)
467{
468 PyObject *t, *r;
469
470 t = complex_divmod(v, w);
471 if (t != NULL) {
472 r = PyTuple_GET_ITEM(t, 0);
473 Py_INCREF(r);
474 Py_DECREF(t);
475 return r;
476 }
477 return NULL;
478}
479
480static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000481complex_neg(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000482{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000483 Py_complex neg;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000484 neg.real = -v->cval.real;
485 neg.imag = -v->cval.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000486 return PyComplex_FromCComplex(neg);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000487}
488
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000489static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000490complex_pos(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000491{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000492 Py_INCREF(v);
493 return (PyObject *)v;
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_abs(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000498{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000499 double result;
500 PyFPE_START_PROTECT("complex_abs", return 0)
501 result = hypot(v->cval.real,v->cval.imag);
Guido van Rossum45b83911997-03-14 04:32:50 +0000502 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000503 return PyFloat_FromDouble(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000504}
505
506static int
Fred Drake4288c802000-07-09 04:36:04 +0000507complex_nonzero(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000508{
Guido van Rossum3bbef601999-01-25 19:42:19 +0000509 return v->cval.real != 0.0 || v->cval.imag != 0.0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000510}
511
512static int
Fred Drake4288c802000-07-09 04:36:04 +0000513complex_coerce(PyObject **pv, PyObject **pw)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000514{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000515 Py_complex cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000516 cval.imag = 0.;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000517 if (PyInt_Check(*pw)) {
518 cval.real = (double)PyInt_AsLong(*pw);
519 *pw = PyComplex_FromCComplex(cval);
520 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000521 return 0;
522 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000523 else if (PyLong_Check(*pw)) {
524 cval.real = PyLong_AsDouble(*pw);
Tim Peters9fffa3e2001-09-04 05:14:19 +0000525 if (cval.real == -1.0 && PyErr_Occurred())
526 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000527 *pw = PyComplex_FromCComplex(cval);
528 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000529 return 0;
530 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000531 else if (PyFloat_Check(*pw)) {
532 cval.real = PyFloat_AsDouble(*pw);
533 *pw = PyComplex_FromCComplex(cval);
534 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000535 return 0;
536 }
537 return 1; /* Can't do it */
538}
539
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000540static PyObject *
Guido van Rossumbe4cbb12001-01-18 01:12:39 +0000541complex_richcompare(PyObject *v, PyObject *w, int op)
542{
543 int c;
544 Py_complex i, j;
545 PyObject *res;
546
547 if (op != Py_EQ && op != Py_NE) {
548 PyErr_SetString(PyExc_TypeError,
549 "cannot compare complex numbers using <, <=, >, >=");
550 return NULL;
551 }
552
553 c = PyNumber_CoerceEx(&v, &w);
554 if (c < 0)
555 return NULL;
556 if (c > 0) {
557 Py_INCREF(Py_NotImplemented);
558 return Py_NotImplemented;
559 }
560 if (!PyComplex_Check(v) || !PyComplex_Check(w)) {
561 Py_DECREF(v);
562 Py_DECREF(w);
563 Py_INCREF(Py_NotImplemented);
564 return Py_NotImplemented;
565 }
566
567 i = ((PyComplexObject *)v)->cval;
568 j = ((PyComplexObject *)w)->cval;
569 Py_DECREF(v);
570 Py_DECREF(w);
571
572 if ((i.real == j.real && i.imag == j.imag) == (op == Py_EQ))
573 res = Py_True;
574 else
575 res = Py_False;
576
577 Py_INCREF(res);
578 return res;
579}
580
581static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000582complex_int(PyObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000583{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000584 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000585 "can't convert complex to int; use e.g. int(abs(z))");
586 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000587}
588
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000589static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000590complex_long(PyObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000591{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000592 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000593 "can't convert complex to long; use e.g. long(abs(z))");
594 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000595}
596
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000597static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000598complex_float(PyObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000599{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000600 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000601 "can't convert complex to float; use e.g. abs(z)");
602 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000603}
604
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000605static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000606complex_conjugate(PyObject *self)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000607{
Guido van Rossum926518b1996-08-19 19:30:45 +0000608 Py_complex c;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000609 c = ((PyComplexObject *)self)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000610 c.imag = -c.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000611 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000612}
613
614static PyMethodDef complex_methods[] = {
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000615 {"conjugate", (PyCFunction)complex_conjugate, METH_NOARGS},
Guido van Rossumf9fca921996-01-12 00:47:05 +0000616 {NULL, NULL} /* sentinel */
617};
618
Tim Peters6d6c1a32001-08-02 04:15:00 +0000619static struct memberlist complex_members[] = {
620 {"real", T_DOUBLE, offsetof(PyComplexObject, cval.real), 0},
621 {"imag", T_DOUBLE, offsetof(PyComplexObject, cval.imag), 0},
622 {0},
623};
Guido van Rossumf9fca921996-01-12 00:47:05 +0000624
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000625static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +0000626complex_subtype_from_string(PyTypeObject *type, PyObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000627{
Tim Peters6d6c1a32001-08-02 04:15:00 +0000628 extern double strtod(const char *, char **);
629 const char *s, *start;
630 char *end;
631 double x=0.0, y=0.0, z;
632 int got_re=0, got_im=0, done=0;
633 int digit_or_dot;
634 int sw_error=0;
635 int sign;
636 char buffer[256]; /* For errors */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000637 int len;
638
639 if (PyString_Check(v)) {
640 s = PyString_AS_STRING(v);
641 len = PyString_GET_SIZE(v);
642 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000643#ifdef Py_USING_UNICODE
Tim Peters6d6c1a32001-08-02 04:15:00 +0000644 else if (PyUnicode_Check(v)) {
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000645 char s_buffer[256];
Tim Peters6d6c1a32001-08-02 04:15:00 +0000646 if (PyUnicode_GET_SIZE(v) >= sizeof(s_buffer)) {
647 PyErr_SetString(PyExc_ValueError,
648 "complex() literal too large to convert");
649 return NULL;
650 }
651 if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
652 PyUnicode_GET_SIZE(v),
653 s_buffer,
654 NULL))
655 return NULL;
656 s = s_buffer;
657 len = (int)strlen(s);
658 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000659#endif
Tim Peters6d6c1a32001-08-02 04:15:00 +0000660 else if (PyObject_AsCharBuffer(v, &s, &len)) {
661 PyErr_SetString(PyExc_TypeError,
662 "complex() arg is not a string");
663 return NULL;
664 }
665
666 /* position on first nonblank */
667 start = s;
668 while (*s && isspace(Py_CHARMASK(*s)))
669 s++;
670 if (s[0] == '\0') {
671 PyErr_SetString(PyExc_ValueError,
672 "complex() arg is an empty string");
673 return NULL;
674 }
675
676 z = -1.0;
677 sign = 1;
678 do {
679
680 switch (*s) {
681
682 case '\0':
683 if (s-start != len) {
684 PyErr_SetString(
685 PyExc_ValueError,
686 "complex() arg contains a null byte");
687 return NULL;
688 }
689 if(!done) sw_error=1;
690 break;
691
692 case '-':
693 sign = -1;
694 /* Fallthrough */
695 case '+':
696 if (done) sw_error=1;
697 s++;
698 if ( *s=='\0'||*s=='+'||*s=='-' ||
699 isspace(Py_CHARMASK(*s)) ) sw_error=1;
700 break;
701
702 case 'J':
703 case 'j':
704 if (got_im || done) {
705 sw_error = 1;
706 break;
707 }
708 if (z<0.0) {
709 y=sign;
710 }
711 else{
712 y=sign*z;
713 }
714 got_im=1;
715 s++;
716 if (*s!='+' && *s!='-' )
717 done=1;
718 break;
719
720 default:
721 if (isspace(Py_CHARMASK(*s))) {
722 while (*s && isspace(Py_CHARMASK(*s)))
723 s++;
724 if (s[0] != '\0')
725 sw_error=1;
726 else
727 done = 1;
728 break;
729 }
730 digit_or_dot =
731 (*s=='.' || isdigit(Py_CHARMASK(*s)));
732 if (done||!digit_or_dot) {
733 sw_error=1;
734 break;
735 }
736 errno = 0;
737 PyFPE_START_PROTECT("strtod", return 0)
738 z = strtod(s, &end) ;
739 PyFPE_END_PROTECT(z)
740 if (errno != 0) {
741 sprintf(buffer,
742 "float() out of range: %.150s", s);
743 PyErr_SetString(
744 PyExc_ValueError,
745 buffer);
746 return NULL;
747 }
748 s=end;
749 if (*s=='J' || *s=='j') {
750
751 break;
752 }
753 if (got_re) {
754 sw_error=1;
755 break;
756 }
757
758 /* accept a real part */
759 x=sign*z;
760 got_re=1;
761 if (got_im) done=1;
762 z = -1.0;
763 sign = 1;
764 break;
765
766 } /* end of switch */
767
768 } while (*s!='\0' && !sw_error);
769
770 if (sw_error) {
771 PyErr_SetString(PyExc_ValueError,
772 "complex() arg is a malformed string");
773 return NULL;
774 }
775
776 return complex_subtype_from_doubles(type, x, y);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000777}
778
Tim Peters6d6c1a32001-08-02 04:15:00 +0000779static PyObject *
780complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
781{
782 PyObject *r, *i, *tmp;
783 PyNumberMethods *nbr, *nbi = NULL;
784 Py_complex cr, ci;
785 int own_r = 0;
786 static char *kwlist[] = {"real", "imag", 0};
787
788 r = Py_False;
789 i = NULL;
790 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:complex", kwlist,
791 &r, &i))
792 return NULL;
793 if (PyString_Check(r) || PyUnicode_Check(r))
794 return complex_subtype_from_string(type, r);
795 if ((nbr = r->ob_type->tp_as_number) == NULL ||
796 nbr->nb_float == NULL ||
797 (i != NULL &&
798 ((nbi = i->ob_type->tp_as_number) == NULL ||
799 nbi->nb_float == NULL))) {
800 PyErr_SetString(PyExc_TypeError,
801 "complex() arg can't be converted to complex");
802 return NULL;
803 }
804 /* XXX Hack to support classes with __complex__ method */
805 if (PyInstance_Check(r)) {
806 static PyObject *complexstr;
807 PyObject *f;
808 if (complexstr == NULL) {
809 complexstr = PyString_InternFromString("__complex__");
810 if (complexstr == NULL)
811 return NULL;
812 }
813 f = PyObject_GetAttr(r, complexstr);
814 if (f == NULL)
815 PyErr_Clear();
816 else {
817 PyObject *args = Py_BuildValue("()");
818 if (args == NULL)
819 return NULL;
820 r = PyEval_CallObject(f, args);
821 Py_DECREF(args);
822 Py_DECREF(f);
823 if (r == NULL)
824 return NULL;
825 own_r = 1;
826 }
827 }
828 if (PyComplex_Check(r)) {
829 cr = ((PyComplexObject*)r)->cval;
830 if (own_r) {
831 Py_DECREF(r);
832 }
833 }
834 else {
835 tmp = PyNumber_Float(r);
836 if (own_r) {
837 Py_DECREF(r);
838 }
839 if (tmp == NULL)
840 return NULL;
841 if (!PyFloat_Check(tmp)) {
842 PyErr_SetString(PyExc_TypeError,
843 "float(r) didn't return a float");
844 Py_DECREF(tmp);
845 return NULL;
846 }
847 cr.real = PyFloat_AsDouble(tmp);
848 Py_DECREF(tmp);
849 cr.imag = 0.0;
850 }
851 if (i == NULL) {
852 ci.real = 0.0;
853 ci.imag = 0.0;
854 }
855 else if (PyComplex_Check(i))
856 ci = ((PyComplexObject*)i)->cval;
857 else {
858 tmp = (*nbi->nb_float)(i);
859 if (tmp == NULL)
860 return NULL;
861 ci.real = PyFloat_AsDouble(tmp);
862 Py_DECREF(tmp);
863 ci.imag = 0.;
864 }
865 cr.real -= ci.imag;
866 cr.imag += ci.real;
867 return complex_subtype_from_c_complex(type, cr);
868}
869
870static char complex_doc[] =
871"complex(real[, imag]) -> complex number\n\
872\n\
873Create a complex number from a real part and an optional imaginary part.\n\
874This is equivalent to (real + imag*1j) where imag defaults to 0.";
875
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000876static PyNumberMethods complex_as_number = {
Guido van Rossumbe4cbb12001-01-18 01:12:39 +0000877 (binaryfunc)complex_add, /* nb_add */
878 (binaryfunc)complex_sub, /* nb_subtract */
879 (binaryfunc)complex_mul, /* nb_multiply */
Guido van Rossum393661d2001-08-31 17:40:15 +0000880 (binaryfunc)complex_classic_div, /* nb_divide */
Guido van Rossumbe4cbb12001-01-18 01:12:39 +0000881 (binaryfunc)complex_remainder, /* nb_remainder */
882 (binaryfunc)complex_divmod, /* nb_divmod */
883 (ternaryfunc)complex_pow, /* nb_power */
884 (unaryfunc)complex_neg, /* nb_negative */
885 (unaryfunc)complex_pos, /* nb_positive */
886 (unaryfunc)complex_abs, /* nb_absolute */
887 (inquiry)complex_nonzero, /* nb_nonzero */
888 0, /* nb_invert */
889 0, /* nb_lshift */
890 0, /* nb_rshift */
891 0, /* nb_and */
892 0, /* nb_xor */
893 0, /* nb_or */
894 (coercion)complex_coerce, /* nb_coerce */
895 (unaryfunc)complex_int, /* nb_int */
896 (unaryfunc)complex_long, /* nb_long */
897 (unaryfunc)complex_float, /* nb_float */
898 0, /* nb_oct */
899 0, /* nb_hex */
Guido van Rossum4668b002001-08-08 05:00:18 +0000900 0, /* nb_inplace_add */
901 0, /* nb_inplace_subtract */
902 0, /* nb_inplace_multiply*/
903 0, /* nb_inplace_divide */
904 0, /* nb_inplace_remainder */
905 0, /* nb_inplace_power */
906 0, /* nb_inplace_lshift */
907 0, /* nb_inplace_rshift */
908 0, /* nb_inplace_and */
909 0, /* nb_inplace_xor */
910 0, /* nb_inplace_or */
911 (binaryfunc)complex_int_div, /* nb_floor_divide */
912 (binaryfunc)complex_div, /* nb_true_divide */
913 0, /* nb_inplace_floor_divide */
914 0, /* nb_inplace_true_divide */
Guido van Rossumf9fca921996-01-12 00:47:05 +0000915};
916
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000917PyTypeObject PyComplex_Type = {
918 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000919 0,
920 "complex",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000921 sizeof(PyComplexObject),
Guido van Rossumf9fca921996-01-12 00:47:05 +0000922 0,
Guido van Rossumbe4cbb12001-01-18 01:12:39 +0000923 (destructor)complex_dealloc, /* tp_dealloc */
924 (printfunc)complex_print, /* tp_print */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000925 0, /* tp_getattr */
Guido van Rossumbe4cbb12001-01-18 01:12:39 +0000926 0, /* tp_setattr */
927 0, /* tp_compare */
928 (reprfunc)complex_repr, /* tp_repr */
929 &complex_as_number, /* tp_as_number */
930 0, /* tp_as_sequence */
931 0, /* tp_as_mapping */
932 (hashfunc)complex_hash, /* tp_hash */
933 0, /* tp_call */
Tim Peters70695122001-03-11 08:37:29 +0000934 (reprfunc)complex_str, /* tp_str */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000935 PyObject_GenericGetAttr, /* tp_getattro */
Guido van Rossumbe4cbb12001-01-18 01:12:39 +0000936 0, /* tp_setattro */
937 0, /* tp_as_buffer */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000938 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
939 complex_doc, /* tp_doc */
Guido van Rossumbe4cbb12001-01-18 01:12:39 +0000940 0, /* tp_traverse */
941 0, /* tp_clear */
942 complex_richcompare, /* tp_richcompare */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000943 0, /* tp_weaklistoffset */
944 0, /* tp_iter */
945 0, /* tp_iternext */
946 complex_methods, /* tp_methods */
947 complex_members, /* tp_members */
948 0, /* tp_getset */
949 0, /* tp_base */
950 0, /* tp_dict */
951 0, /* tp_descr_get */
952 0, /* tp_descr_set */
953 0, /* tp_dictoffset */
954 0, /* tp_init */
955 0, /* tp_alloc */
956 complex_new, /* tp_new */
Guido van Rossumf9fca921996-01-12 00:47:05 +0000957};
958
959#endif