blob: dde64498936c0758102a00c237b80752974d8db5 [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
Martin v. Löwis655c9552001-09-05 14:45:54 +000029#ifdef SCO_ATAN2_BUG
30/*
31 * UnixWare 7+ is known to have a bug in atan2 that will return PI instead
32 * of ZERO (0) if the first argument is ZERO(0).
33 */
34static double atan2_sco(double x, double y)
35{
36 if (x == 0.0)
37 return (double)0.0;
38 return atan2(x, y);
39}
40#define ATAN2 atan2_sco
41#else
42#define ATAN2 atan2
43#endif
44
Guido van Rossumf9fca921996-01-12 00:47:05 +000045/* elementary operations on complex numbers */
46
Guido van Rossum9e720e31996-07-21 02:31:35 +000047static Py_complex c_1 = {1., 0.};
Guido van Rossumf9fca921996-01-12 00:47:05 +000048
Tim Peters0f336042001-03-18 08:21:57 +000049Py_complex
50c_sum(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +000051{
Guido van Rossum9e720e31996-07-21 02:31:35 +000052 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000053 r.real = a.real + b.real;
54 r.imag = a.imag + b.imag;
55 return r;
56}
57
Tim Peters0f336042001-03-18 08:21:57 +000058Py_complex
59c_diff(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +000060{
Guido van Rossum9e720e31996-07-21 02:31:35 +000061 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000062 r.real = a.real - b.real;
63 r.imag = a.imag - b.imag;
64 return r;
65}
66
Tim Peters0f336042001-03-18 08:21:57 +000067Py_complex
68c_neg(Py_complex a)
Guido van Rossumf9fca921996-01-12 00:47:05 +000069{
Guido van Rossum9e720e31996-07-21 02:31:35 +000070 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000071 r.real = -a.real;
72 r.imag = -a.imag;
73 return r;
74}
75
Tim Peters0f336042001-03-18 08:21:57 +000076Py_complex
77c_prod(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +000078{
Guido van Rossum9e720e31996-07-21 02:31:35 +000079 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000080 r.real = a.real*b.real - a.imag*b.imag;
81 r.imag = a.real*b.imag + a.imag*b.real;
82 return r;
83}
84
Tim Peters0f336042001-03-18 08:21:57 +000085Py_complex
86c_quot(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +000087{
Tim Peters0f336042001-03-18 08:21:57 +000088 /******************************************************************
89 This was the original algorithm. It's grossly prone to spurious
90 overflow and underflow errors. It also merrily divides by 0 despite
91 checking for that(!). The code still serves a doc purpose here, as
92 the algorithm following is a simple by-cases transformation of this
93 one:
94
Guido van Rossum9e720e31996-07-21 02:31:35 +000095 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000096 double d = b.real*b.real + b.imag*b.imag;
97 if (d == 0.)
Guido van Rossum96783941997-05-20 18:21:34 +000098 errno = EDOM;
Guido van Rossumf9fca921996-01-12 00:47:05 +000099 r.real = (a.real*b.real + a.imag*b.imag)/d;
100 r.imag = (a.imag*b.real - a.real*b.imag)/d;
101 return r;
Tim Peters0f336042001-03-18 08:21:57 +0000102 ******************************************************************/
103
104 /* This algorithm is better, and is pretty obvious: first divide the
105 * numerators and denominator by whichever of {b.real, b.imag} has
106 * larger magnitude. The earliest reference I found was to CACM
107 * Algorithm 116 (Complex Division, Robert L. Smith, Stanford
108 * University). As usual, though, we're still ignoring all IEEE
109 * endcases.
110 */
111 Py_complex r; /* the result */
112 const double abs_breal = b.real < 0 ? -b.real : b.real;
113 const double abs_bimag = b.imag < 0 ? -b.imag : b.imag;
114
115 if (abs_breal >= abs_bimag) {
116 /* divide tops and bottom by b.real */
117 if (abs_breal == 0.0) {
118 errno = EDOM;
119 r.real = r.imag = 0.0;
120 }
121 else {
122 const double ratio = b.imag / b.real;
123 const double denom = b.real + b.imag * ratio;
124 r.real = (a.real + a.imag * ratio) / denom;
125 r.imag = (a.imag - a.real * ratio) / denom;
126 }
127 }
128 else {
129 /* divide tops and bottom by b.imag */
130 const double ratio = b.real / b.imag;
131 const double denom = b.real * ratio + b.imag;
132 assert(b.imag != 0.0);
133 r.real = (a.real * ratio + a.imag) / denom;
134 r.imag = (a.imag * ratio - a.real) / denom;
135 }
136 return r;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000137}
138
Tim Peters0f336042001-03-18 08:21:57 +0000139Py_complex
140c_pow(Py_complex a, Py_complex b)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000141{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000142 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000143 double vabs,len,at,phase;
144 if (b.real == 0. && b.imag == 0.) {
145 r.real = 1.;
146 r.imag = 0.;
147 }
148 else if (a.real == 0. && a.imag == 0.) {
149 if (b.imag != 0. || b.real < 0.)
Guido van Rossum96783941997-05-20 18:21:34 +0000150 errno = ERANGE;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000151 r.real = 0.;
152 r.imag = 0.;
153 }
154 else {
155 vabs = hypot(a.real,a.imag);
156 len = pow(vabs,b.real);
Martin v. Löwis655c9552001-09-05 14:45:54 +0000157 at = ATAN2(a.imag, a.real);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000158 phase = at*b.real;
159 if (b.imag != 0.0) {
160 len /= exp(at*b.imag);
161 phase += b.imag*log(vabs);
162 }
163 r.real = len*cos(phase);
164 r.imag = len*sin(phase);
165 }
166 return r;
167}
168
Tim Peters0f336042001-03-18 08:21:57 +0000169static Py_complex
170c_powu(Py_complex x, long n)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000171{
Guido van Rossum926518b1996-08-19 19:30:45 +0000172 Py_complex r, p;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000173 long mask = 1;
Guido van Rossum926518b1996-08-19 19:30:45 +0000174 r = c_1;
175 p = x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000176 while (mask > 0 && n >= mask) {
177 if (n & mask)
178 r = c_prod(r,p);
179 mask <<= 1;
180 p = c_prod(p,p);
181 }
182 return r;
183}
184
Tim Peters0f336042001-03-18 08:21:57 +0000185static Py_complex
186c_powi(Py_complex x, long n)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000187{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000188 Py_complex cn;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000189
190 if (n > 100 || n < -100) {
191 cn.real = (double) n;
192 cn.imag = 0.;
193 return c_pow(x,cn);
194 }
195 else if (n > 0)
196 return c_powu(x,n);
197 else
198 return c_quot(c_1,c_powu(x,-n));
199
200}
201
Tim Peters6d6c1a32001-08-02 04:15:00 +0000202static PyObject *
203complex_subtype_from_c_complex(PyTypeObject *type, Py_complex cval)
204{
205 PyObject *op;
206
207 op = PyType_GenericAlloc(type, 0);
208 if (op != NULL)
209 ((PyComplexObject *)op)->cval = cval;
210 return op;
211}
212
Guido van Rossumf9fca921996-01-12 00:47:05 +0000213PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000214PyComplex_FromCComplex(Py_complex cval)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000215{
Guido van Rossumb18618d2000-05-03 23:44:39 +0000216 register PyComplexObject *op;
217
218 /* PyObject_New is inlined */
219 op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject));
Guido van Rossumf9fca921996-01-12 00:47:05 +0000220 if (op == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000221 return PyErr_NoMemory();
Guido van Rossumb18618d2000-05-03 23:44:39 +0000222 PyObject_INIT(op, &PyComplex_Type);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000223 op->cval = cval;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000224 return (PyObject *) op;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000225}
226
Tim Peters6d6c1a32001-08-02 04:15:00 +0000227static PyObject *
228complex_subtype_from_doubles(PyTypeObject *type, double real, double imag)
229{
230 Py_complex c;
231 c.real = real;
232 c.imag = imag;
233 return complex_subtype_from_c_complex(type, c);
234}
235
Guido van Rossumf9fca921996-01-12 00:47:05 +0000236PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000237PyComplex_FromDoubles(double real, double imag)
Guido van Rossum926518b1996-08-19 19:30:45 +0000238{
239 Py_complex c;
240 c.real = real;
241 c.imag = imag;
242 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000243}
244
245double
Fred Drake4288c802000-07-09 04:36:04 +0000246PyComplex_RealAsDouble(PyObject *op)
Guido van Rossum926518b1996-08-19 19:30:45 +0000247{
248 if (PyComplex_Check(op)) {
249 return ((PyComplexObject *)op)->cval.real;
Fred Drake4288c802000-07-09 04:36:04 +0000250 }
251 else {
Guido van Rossum926518b1996-08-19 19:30:45 +0000252 return PyFloat_AsDouble(op);
253 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000254}
255
256double
Fred Drake4288c802000-07-09 04:36:04 +0000257PyComplex_ImagAsDouble(PyObject *op)
Guido van Rossum926518b1996-08-19 19:30:45 +0000258{
259 if (PyComplex_Check(op)) {
260 return ((PyComplexObject *)op)->cval.imag;
Fred Drake4288c802000-07-09 04:36:04 +0000261 }
262 else {
Guido van Rossum926518b1996-08-19 19:30:45 +0000263 return 0.0;
264 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000265}
266
Guido van Rossum9e720e31996-07-21 02:31:35 +0000267Py_complex
Fred Drake4288c802000-07-09 04:36:04 +0000268PyComplex_AsCComplex(PyObject *op)
Guido van Rossum926518b1996-08-19 19:30:45 +0000269{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000270 Py_complex cv;
Guido van Rossumcf3d1081996-01-12 01:21:14 +0000271 if (PyComplex_Check(op)) {
272 return ((PyComplexObject *)op)->cval;
Fred Drake4288c802000-07-09 04:36:04 +0000273 }
274 else {
Guido van Rossumcf3d1081996-01-12 01:21:14 +0000275 cv.real = PyFloat_AsDouble(op);
276 cv.imag = 0.;
277 return cv;
Tim Peters70695122001-03-11 08:37:29 +0000278 }
Guido van Rossumcf3d1081996-01-12 01:21:14 +0000279}
280
Guido van Rossumf9fca921996-01-12 00:47:05 +0000281static void
Fred Drake4288c802000-07-09 04:36:04 +0000282complex_dealloc(PyObject *op)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000283{
Guido van Rossumb18618d2000-05-03 23:44:39 +0000284 PyObject_DEL(op);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000285}
286
287
Guido van Rossum363078a1996-05-24 20:45:01 +0000288static void
Tim Peters70695122001-03-11 08:37:29 +0000289complex_to_buf(char *buf, PyComplexObject *v, int precision)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000290{
291 if (v->cval.real == 0.)
Tim Peters70695122001-03-11 08:37:29 +0000292 sprintf(buf, "%.*gj", precision, v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000293 else
Tim Peters70695122001-03-11 08:37:29 +0000294 sprintf(buf, "(%.*g%+.*gj)", precision, v->cval.real,
295 precision, v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000296}
297
298static int
Fred Drake4288c802000-07-09 04:36:04 +0000299complex_print(PyComplexObject *v, FILE *fp, int flags)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000300{
301 char buf[100];
Tim Peters70695122001-03-11 08:37:29 +0000302 complex_to_buf(buf, v,
303 (flags & Py_PRINT_RAW) ? PREC_STR : PREC_REPR);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000304 fputs(buf, fp);
305 return 0;
306}
307
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000308static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000309complex_repr(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000310{
311 char buf[100];
Tim Peters70695122001-03-11 08:37:29 +0000312 complex_to_buf(buf, v, PREC_REPR);
313 return PyString_FromString(buf);
314}
315
316static PyObject *
317complex_str(PyComplexObject *v)
318{
319 char buf[100];
320 complex_to_buf(buf, v, PREC_STR);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000321 return PyString_FromString(buf);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000322}
323
Guido van Rossumf9fca921996-01-12 00:47:05 +0000324static long
Fred Drake4288c802000-07-09 04:36:04 +0000325complex_hash(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000326{
Tim Peters39dce292000-08-15 03:34:48 +0000327 long hashreal, hashimag, combined;
328 hashreal = _Py_HashDouble(v->cval.real);
329 if (hashreal == -1)
330 return -1;
331 hashimag = _Py_HashDouble(v->cval.imag);
332 if (hashimag == -1)
333 return -1;
334 /* Note: if the imaginary part is 0, hashimag is 0 now,
335 * so the following returns hashreal unchanged. This is
336 * important because numbers of different types that
337 * compare equal must have the same hash value, so that
338 * hash(x + 0*j) must equal hash(x).
339 */
340 combined = hashreal + 1000003 * hashimag;
341 if (combined == -1)
342 combined = -2;
343 return combined;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000344}
345
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000346static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000347complex_add(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000348{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000349 Py_complex result;
350 PyFPE_START_PROTECT("complex_add", return 0)
351 result = c_sum(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000352 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000353 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000354}
355
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000356static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000357complex_sub(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000358{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000359 Py_complex result;
360 PyFPE_START_PROTECT("complex_sub", return 0)
361 result = c_diff(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000362 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000363 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000364}
365
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000366static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000367complex_mul(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000368{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000369 Py_complex result;
370 PyFPE_START_PROTECT("complex_mul", return 0)
371 result = c_prod(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000372 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000373 return PyComplex_FromCComplex(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000374}
375
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000376static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000377complex_div(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000378{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000379 Py_complex quot;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000380 PyFPE_START_PROTECT("complex_div", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000381 errno = 0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000382 quot = c_quot(v->cval,w->cval);
Guido van Rossum45b83911997-03-14 04:32:50 +0000383 PyFPE_END_PROTECT(quot)
Guido van Rossum96783941997-05-20 18:21:34 +0000384 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000385 PyErr_SetString(PyExc_ZeroDivisionError, "complex division");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000386 return NULL;
387 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000388 return PyComplex_FromCComplex(quot);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000389}
390
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000391static PyObject *
Guido van Rossum393661d2001-08-31 17:40:15 +0000392complex_classic_div(PyComplexObject *v, PyComplexObject *w)
393{
394 Py_complex quot;
395
Guido van Rossum1832de42001-09-04 03:51:09 +0000396 if (Py_DivisionWarningFlag >= 2 &&
Guido van Rossum393661d2001-08-31 17:40:15 +0000397 PyErr_Warn(PyExc_DeprecationWarning,
398 "classic complex division") < 0)
399 return NULL;
400
401 PyFPE_START_PROTECT("complex_classic_div", return 0)
402 errno = 0;
403 quot = c_quot(v->cval,w->cval);
404 PyFPE_END_PROTECT(quot)
405 if (errno == EDOM) {
406 PyErr_SetString(PyExc_ZeroDivisionError, "complex division");
407 return NULL;
408 }
409 return PyComplex_FromCComplex(quot);
410}
411
412static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000413complex_remainder(PyComplexObject *v, PyComplexObject *w)
Guido van Rossumee09fc11996-09-11 13:55:55 +0000414{
Guido van Rossum3be12e91996-09-12 20:56:18 +0000415 Py_complex div, mod;
Guido van Rossum96783941997-05-20 18:21:34 +0000416 errno = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000417 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
Guido van Rossum96783941997-05-20 18:21:34 +0000418 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000419 PyErr_SetString(PyExc_ZeroDivisionError, "complex remainder");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000420 return NULL;
421 }
422 div.real = floor(div.real); /* Use the floor of the real part. */
423 div.imag = 0.0;
424 mod = c_diff(v->cval, c_prod(w->cval, div));
425
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000426 return PyComplex_FromCComplex(mod);
Guido van Rossumee09fc11996-09-11 13:55:55 +0000427}
428
Guido van Rossumee09fc11996-09-11 13:55:55 +0000429
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000430static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000431complex_divmod(PyComplexObject *v, PyComplexObject *w)
Guido van Rossum3be12e91996-09-12 20:56:18 +0000432{
433 Py_complex div, mod;
434 PyObject *d, *m, *z;
Guido van Rossum96783941997-05-20 18:21:34 +0000435 errno = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000436 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
Guido van Rossum96783941997-05-20 18:21:34 +0000437 if (errno == EDOM) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000438 PyErr_SetString(PyExc_ZeroDivisionError, "complex divmod()");
Guido van Rossum3be12e91996-09-12 20:56:18 +0000439 return NULL;
440 }
441 div.real = floor(div.real); /* Use the floor of the real part. */
442 div.imag = 0.0;
443 mod = c_diff(v->cval, c_prod(w->cval, div));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000444 d = PyComplex_FromCComplex(div);
445 m = PyComplex_FromCComplex(mod);
446 z = Py_BuildValue("(OO)", d, m);
Guido van Rossum3be12e91996-09-12 20:56:18 +0000447 Py_XDECREF(d);
448 Py_XDECREF(m);
449 return z;
450}
Guido van Rossumf9fca921996-01-12 00:47:05 +0000451
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000452static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000453complex_pow(PyComplexObject *v, PyObject *w, PyComplexObject *z)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000454{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000455 Py_complex p;
456 Py_complex exponent;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000457 long int_exponent;
458
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000459 if ((PyObject *)z!=Py_None) {
460 PyErr_SetString(PyExc_ValueError, "complex modulo");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000461 return NULL;
462 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000463 PyFPE_START_PROTECT("complex_pow", return 0)
Guido van Rossum96783941997-05-20 18:21:34 +0000464 errno = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000465 exponent = ((PyComplexObject*)w)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000466 int_exponent = (long)exponent.real;
467 if (exponent.imag == 0. && exponent.real == int_exponent)
468 p = c_powi(v->cval,int_exponent);
469 else
470 p = c_pow(v->cval,exponent);
471
Guido van Rossum45b83911997-03-14 04:32:50 +0000472 PyFPE_END_PROTECT(p)
Guido van Rossum96783941997-05-20 18:21:34 +0000473 if (errno == ERANGE) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000474 PyErr_SetString(PyExc_ValueError,
475 "0.0 to a negative or complex power");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000476 return NULL;
477 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000478 return PyComplex_FromCComplex(p);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000479}
480
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000481static PyObject *
Guido van Rossum4668b002001-08-08 05:00:18 +0000482complex_int_div(PyComplexObject *v, PyComplexObject *w)
483{
484 PyObject *t, *r;
485
486 t = complex_divmod(v, w);
487 if (t != NULL) {
488 r = PyTuple_GET_ITEM(t, 0);
489 Py_INCREF(r);
490 Py_DECREF(t);
491 return r;
492 }
493 return NULL;
494}
495
496static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000497complex_neg(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000498{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000499 Py_complex neg;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000500 neg.real = -v->cval.real;
501 neg.imag = -v->cval.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000502 return PyComplex_FromCComplex(neg);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000503}
504
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000505static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000506complex_pos(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000507{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000508 Py_INCREF(v);
509 return (PyObject *)v;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000510}
511
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000512static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000513complex_abs(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000514{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000515 double result;
516 PyFPE_START_PROTECT("complex_abs", return 0)
517 result = hypot(v->cval.real,v->cval.imag);
Guido van Rossum45b83911997-03-14 04:32:50 +0000518 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000519 return PyFloat_FromDouble(result);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000520}
521
522static int
Fred Drake4288c802000-07-09 04:36:04 +0000523complex_nonzero(PyComplexObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000524{
Guido van Rossum3bbef601999-01-25 19:42:19 +0000525 return v->cval.real != 0.0 || v->cval.imag != 0.0;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000526}
527
528static int
Fred Drake4288c802000-07-09 04:36:04 +0000529complex_coerce(PyObject **pv, PyObject **pw)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000530{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000531 Py_complex cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000532 cval.imag = 0.;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000533 if (PyInt_Check(*pw)) {
534 cval.real = (double)PyInt_AsLong(*pw);
535 *pw = PyComplex_FromCComplex(cval);
536 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000537 return 0;
538 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000539 else if (PyLong_Check(*pw)) {
540 cval.real = PyLong_AsDouble(*pw);
Tim Peters9fffa3e2001-09-04 05:14:19 +0000541 if (cval.real == -1.0 && PyErr_Occurred())
542 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000543 *pw = PyComplex_FromCComplex(cval);
544 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000545 return 0;
546 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000547 else if (PyFloat_Check(*pw)) {
548 cval.real = PyFloat_AsDouble(*pw);
549 *pw = PyComplex_FromCComplex(cval);
550 Py_INCREF(*pv);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000551 return 0;
552 }
553 return 1; /* Can't do it */
554}
555
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000556static PyObject *
Guido van Rossumbe4cbb12001-01-18 01:12:39 +0000557complex_richcompare(PyObject *v, PyObject *w, int op)
558{
559 int c;
560 Py_complex i, j;
561 PyObject *res;
562
563 if (op != Py_EQ && op != Py_NE) {
564 PyErr_SetString(PyExc_TypeError,
565 "cannot compare complex numbers using <, <=, >, >=");
566 return NULL;
567 }
568
569 c = PyNumber_CoerceEx(&v, &w);
570 if (c < 0)
571 return NULL;
572 if (c > 0) {
573 Py_INCREF(Py_NotImplemented);
574 return Py_NotImplemented;
575 }
576 if (!PyComplex_Check(v) || !PyComplex_Check(w)) {
577 Py_DECREF(v);
578 Py_DECREF(w);
579 Py_INCREF(Py_NotImplemented);
580 return Py_NotImplemented;
581 }
582
583 i = ((PyComplexObject *)v)->cval;
584 j = ((PyComplexObject *)w)->cval;
585 Py_DECREF(v);
586 Py_DECREF(w);
587
588 if ((i.real == j.real && i.imag == j.imag) == (op == Py_EQ))
589 res = Py_True;
590 else
591 res = Py_False;
592
593 Py_INCREF(res);
594 return res;
595}
596
597static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000598complex_int(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 int; use e.g. int(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 *
Fred Drake4288c802000-07-09 04:36:04 +0000606complex_long(PyObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000607{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000608 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000609 "can't convert complex to long; use e.g. long(abs(z))");
610 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000611}
612
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000613static PyObject *
Fred Drake4288c802000-07-09 04:36:04 +0000614complex_float(PyObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000615{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000616 PyErr_SetString(PyExc_TypeError,
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000617 "can't convert complex to float; use e.g. abs(z)");
618 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000619}
620
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000621static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000622complex_conjugate(PyObject *self)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000623{
Guido van Rossum926518b1996-08-19 19:30:45 +0000624 Py_complex c;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000625 c = ((PyComplexObject *)self)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000626 c.imag = -c.imag;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000627 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000628}
629
630static PyMethodDef complex_methods[] = {
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000631 {"conjugate", (PyCFunction)complex_conjugate, METH_NOARGS},
Guido van Rossumf9fca921996-01-12 00:47:05 +0000632 {NULL, NULL} /* sentinel */
633};
634
Tim Peters6d6c1a32001-08-02 04:15:00 +0000635static struct memberlist complex_members[] = {
636 {"real", T_DOUBLE, offsetof(PyComplexObject, cval.real), 0},
637 {"imag", T_DOUBLE, offsetof(PyComplexObject, cval.imag), 0},
638 {0},
639};
Guido van Rossumf9fca921996-01-12 00:47:05 +0000640
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000641static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +0000642complex_subtype_from_string(PyTypeObject *type, PyObject *v)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000643{
Tim Peters6d6c1a32001-08-02 04:15:00 +0000644 extern double strtod(const char *, char **);
645 const char *s, *start;
646 char *end;
647 double x=0.0, y=0.0, z;
648 int got_re=0, got_im=0, done=0;
649 int digit_or_dot;
650 int sw_error=0;
651 int sign;
652 char buffer[256]; /* For errors */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000653 int len;
654
655 if (PyString_Check(v)) {
656 s = PyString_AS_STRING(v);
657 len = PyString_GET_SIZE(v);
658 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000659#ifdef Py_USING_UNICODE
Tim Peters6d6c1a32001-08-02 04:15:00 +0000660 else if (PyUnicode_Check(v)) {
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000661 char s_buffer[256];
Tim Peters6d6c1a32001-08-02 04:15:00 +0000662 if (PyUnicode_GET_SIZE(v) >= sizeof(s_buffer)) {
663 PyErr_SetString(PyExc_ValueError,
664 "complex() literal too large to convert");
665 return NULL;
666 }
667 if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
668 PyUnicode_GET_SIZE(v),
669 s_buffer,
670 NULL))
671 return NULL;
672 s = s_buffer;
673 len = (int)strlen(s);
674 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000675#endif
Tim Peters6d6c1a32001-08-02 04:15:00 +0000676 else if (PyObject_AsCharBuffer(v, &s, &len)) {
677 PyErr_SetString(PyExc_TypeError,
678 "complex() arg is not a string");
679 return NULL;
680 }
681
682 /* position on first nonblank */
683 start = s;
684 while (*s && isspace(Py_CHARMASK(*s)))
685 s++;
686 if (s[0] == '\0') {
687 PyErr_SetString(PyExc_ValueError,
688 "complex() arg is an empty string");
689 return NULL;
690 }
691
692 z = -1.0;
693 sign = 1;
694 do {
695
696 switch (*s) {
697
698 case '\0':
699 if (s-start != len) {
700 PyErr_SetString(
701 PyExc_ValueError,
702 "complex() arg contains a null byte");
703 return NULL;
704 }
705 if(!done) sw_error=1;
706 break;
707
708 case '-':
709 sign = -1;
710 /* Fallthrough */
711 case '+':
712 if (done) sw_error=1;
713 s++;
714 if ( *s=='\0'||*s=='+'||*s=='-' ||
715 isspace(Py_CHARMASK(*s)) ) sw_error=1;
716 break;
717
718 case 'J':
719 case 'j':
720 if (got_im || done) {
721 sw_error = 1;
722 break;
723 }
724 if (z<0.0) {
725 y=sign;
726 }
727 else{
728 y=sign*z;
729 }
730 got_im=1;
731 s++;
732 if (*s!='+' && *s!='-' )
733 done=1;
734 break;
735
736 default:
737 if (isspace(Py_CHARMASK(*s))) {
738 while (*s && isspace(Py_CHARMASK(*s)))
739 s++;
740 if (s[0] != '\0')
741 sw_error=1;
742 else
743 done = 1;
744 break;
745 }
746 digit_or_dot =
747 (*s=='.' || isdigit(Py_CHARMASK(*s)));
748 if (done||!digit_or_dot) {
749 sw_error=1;
750 break;
751 }
752 errno = 0;
753 PyFPE_START_PROTECT("strtod", return 0)
754 z = strtod(s, &end) ;
755 PyFPE_END_PROTECT(z)
756 if (errno != 0) {
757 sprintf(buffer,
758 "float() out of range: %.150s", s);
759 PyErr_SetString(
760 PyExc_ValueError,
761 buffer);
762 return NULL;
763 }
764 s=end;
765 if (*s=='J' || *s=='j') {
766
767 break;
768 }
769 if (got_re) {
770 sw_error=1;
771 break;
772 }
773
774 /* accept a real part */
775 x=sign*z;
776 got_re=1;
777 if (got_im) done=1;
778 z = -1.0;
779 sign = 1;
780 break;
781
782 } /* end of switch */
783
784 } while (*s!='\0' && !sw_error);
785
786 if (sw_error) {
787 PyErr_SetString(PyExc_ValueError,
788 "complex() arg is a malformed string");
789 return NULL;
790 }
791
792 return complex_subtype_from_doubles(type, x, y);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000793}
794
Tim Peters6d6c1a32001-08-02 04:15:00 +0000795static PyObject *
796complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
797{
798 PyObject *r, *i, *tmp;
799 PyNumberMethods *nbr, *nbi = NULL;
800 Py_complex cr, ci;
801 int own_r = 0;
802 static char *kwlist[] = {"real", "imag", 0};
803
804 r = Py_False;
805 i = NULL;
806 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:complex", kwlist,
807 &r, &i))
808 return NULL;
809 if (PyString_Check(r) || PyUnicode_Check(r))
810 return complex_subtype_from_string(type, r);
811 if ((nbr = r->ob_type->tp_as_number) == NULL ||
812 nbr->nb_float == NULL ||
813 (i != NULL &&
814 ((nbi = i->ob_type->tp_as_number) == NULL ||
815 nbi->nb_float == NULL))) {
816 PyErr_SetString(PyExc_TypeError,
817 "complex() arg can't be converted to complex");
818 return NULL;
819 }
820 /* XXX Hack to support classes with __complex__ method */
821 if (PyInstance_Check(r)) {
822 static PyObject *complexstr;
823 PyObject *f;
824 if (complexstr == NULL) {
825 complexstr = PyString_InternFromString("__complex__");
826 if (complexstr == NULL)
827 return NULL;
828 }
829 f = PyObject_GetAttr(r, complexstr);
830 if (f == NULL)
831 PyErr_Clear();
832 else {
833 PyObject *args = Py_BuildValue("()");
834 if (args == NULL)
835 return NULL;
836 r = PyEval_CallObject(f, args);
837 Py_DECREF(args);
838 Py_DECREF(f);
839 if (r == NULL)
840 return NULL;
841 own_r = 1;
842 }
843 }
844 if (PyComplex_Check(r)) {
845 cr = ((PyComplexObject*)r)->cval;
846 if (own_r) {
847 Py_DECREF(r);
848 }
849 }
850 else {
851 tmp = PyNumber_Float(r);
852 if (own_r) {
853 Py_DECREF(r);
854 }
855 if (tmp == NULL)
856 return NULL;
857 if (!PyFloat_Check(tmp)) {
858 PyErr_SetString(PyExc_TypeError,
859 "float(r) didn't return a float");
860 Py_DECREF(tmp);
861 return NULL;
862 }
863 cr.real = PyFloat_AsDouble(tmp);
864 Py_DECREF(tmp);
865 cr.imag = 0.0;
866 }
867 if (i == NULL) {
868 ci.real = 0.0;
869 ci.imag = 0.0;
870 }
871 else if (PyComplex_Check(i))
872 ci = ((PyComplexObject*)i)->cval;
873 else {
874 tmp = (*nbi->nb_float)(i);
875 if (tmp == NULL)
876 return NULL;
877 ci.real = PyFloat_AsDouble(tmp);
878 Py_DECREF(tmp);
879 ci.imag = 0.;
880 }
881 cr.real -= ci.imag;
882 cr.imag += ci.real;
883 return complex_subtype_from_c_complex(type, cr);
884}
885
886static char complex_doc[] =
887"complex(real[, imag]) -> complex number\n\
888\n\
889Create a complex number from a real part and an optional imaginary part.\n\
890This is equivalent to (real + imag*1j) where imag defaults to 0.";
891
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000892static PyNumberMethods complex_as_number = {
Guido van Rossumbe4cbb12001-01-18 01:12:39 +0000893 (binaryfunc)complex_add, /* nb_add */
894 (binaryfunc)complex_sub, /* nb_subtract */
895 (binaryfunc)complex_mul, /* nb_multiply */
Guido van Rossum393661d2001-08-31 17:40:15 +0000896 (binaryfunc)complex_classic_div, /* nb_divide */
Guido van Rossumbe4cbb12001-01-18 01:12:39 +0000897 (binaryfunc)complex_remainder, /* nb_remainder */
898 (binaryfunc)complex_divmod, /* nb_divmod */
899 (ternaryfunc)complex_pow, /* nb_power */
900 (unaryfunc)complex_neg, /* nb_negative */
901 (unaryfunc)complex_pos, /* nb_positive */
902 (unaryfunc)complex_abs, /* nb_absolute */
903 (inquiry)complex_nonzero, /* nb_nonzero */
904 0, /* nb_invert */
905 0, /* nb_lshift */
906 0, /* nb_rshift */
907 0, /* nb_and */
908 0, /* nb_xor */
909 0, /* nb_or */
910 (coercion)complex_coerce, /* nb_coerce */
911 (unaryfunc)complex_int, /* nb_int */
912 (unaryfunc)complex_long, /* nb_long */
913 (unaryfunc)complex_float, /* nb_float */
914 0, /* nb_oct */
915 0, /* nb_hex */
Guido van Rossum4668b002001-08-08 05:00:18 +0000916 0, /* nb_inplace_add */
917 0, /* nb_inplace_subtract */
918 0, /* nb_inplace_multiply*/
919 0, /* nb_inplace_divide */
920 0, /* nb_inplace_remainder */
921 0, /* nb_inplace_power */
922 0, /* nb_inplace_lshift */
923 0, /* nb_inplace_rshift */
924 0, /* nb_inplace_and */
925 0, /* nb_inplace_xor */
926 0, /* nb_inplace_or */
927 (binaryfunc)complex_int_div, /* nb_floor_divide */
928 (binaryfunc)complex_div, /* nb_true_divide */
929 0, /* nb_inplace_floor_divide */
930 0, /* nb_inplace_true_divide */
Guido van Rossumf9fca921996-01-12 00:47:05 +0000931};
932
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000933PyTypeObject PyComplex_Type = {
934 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumf9fca921996-01-12 00:47:05 +0000935 0,
936 "complex",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000937 sizeof(PyComplexObject),
Guido van Rossumf9fca921996-01-12 00:47:05 +0000938 0,
Guido van Rossumbe4cbb12001-01-18 01:12:39 +0000939 (destructor)complex_dealloc, /* tp_dealloc */
940 (printfunc)complex_print, /* tp_print */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000941 0, /* tp_getattr */
Guido van Rossumbe4cbb12001-01-18 01:12:39 +0000942 0, /* tp_setattr */
943 0, /* tp_compare */
944 (reprfunc)complex_repr, /* tp_repr */
945 &complex_as_number, /* tp_as_number */
946 0, /* tp_as_sequence */
947 0, /* tp_as_mapping */
948 (hashfunc)complex_hash, /* tp_hash */
949 0, /* tp_call */
Tim Peters70695122001-03-11 08:37:29 +0000950 (reprfunc)complex_str, /* tp_str */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000951 PyObject_GenericGetAttr, /* tp_getattro */
Guido van Rossumbe4cbb12001-01-18 01:12:39 +0000952 0, /* tp_setattro */
953 0, /* tp_as_buffer */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000954 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
955 complex_doc, /* tp_doc */
Guido van Rossumbe4cbb12001-01-18 01:12:39 +0000956 0, /* tp_traverse */
957 0, /* tp_clear */
958 complex_richcompare, /* tp_richcompare */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000959 0, /* tp_weaklistoffset */
960 0, /* tp_iter */
961 0, /* tp_iternext */
962 complex_methods, /* tp_methods */
963 complex_members, /* tp_members */
964 0, /* tp_getset */
965 0, /* tp_base */
966 0, /* tp_dict */
967 0, /* tp_descr_get */
968 0, /* tp_descr_set */
969 0, /* tp_dictoffset */
970 0, /* tp_init */
971 0, /* tp_alloc */
972 complex_new, /* tp_new */
Guido van Rossumf9fca921996-01-12 00:47:05 +0000973};
974
975#endif