cpython/Objects/complexobject.c

630 lines
14 KiB
C
Raw Normal View History

1996-01-11 20:47:05 -04:00
/* Complex object implementation */
/* Borrows heavily from floatobject.c */
/* Submitted by Jim Hugunin */
1996-01-11 20:47:05 -04:00
#ifndef WITHOUT_COMPLEX
1997-05-02 00:12:38 -03:00
#include "Python.h"
1996-01-11 20:47:05 -04:00
/* Precisions used by repr() and str(), respectively.
The repr() precision (17 significant decimal digits) is the minimal number
that is guaranteed to have enough precision so that if the number is read
back in the exact same binary value is recreated. This is true for IEEE
floating point by design, and also happens to work for all other modern
hardware.
The str() precision is chosen so that in most cases, the rounding noise
created by various operations is suppressed, while giving plenty of
precision for practical use.
*/
#define PREC_REPR 17
#define PREC_STR 12
1996-01-11 20:47:05 -04:00
/* elementary operations on complex numbers */
1996-07-20 23:31:35 -03:00
static Py_complex c_1 = {1., 0.};
1996-01-11 20:47:05 -04:00
Py_complex
c_sum(Py_complex a, Py_complex b)
1996-01-11 20:47:05 -04:00
{
1996-07-20 23:31:35 -03:00
Py_complex r;
1996-01-11 20:47:05 -04:00
r.real = a.real + b.real;
r.imag = a.imag + b.imag;
return r;
}
Py_complex
c_diff(Py_complex a, Py_complex b)
1996-01-11 20:47:05 -04:00
{
1996-07-20 23:31:35 -03:00
Py_complex r;
1996-01-11 20:47:05 -04:00
r.real = a.real - b.real;
r.imag = a.imag - b.imag;
return r;
}
Py_complex
c_neg(Py_complex a)
1996-01-11 20:47:05 -04:00
{
1996-07-20 23:31:35 -03:00
Py_complex r;
1996-01-11 20:47:05 -04:00
r.real = -a.real;
r.imag = -a.imag;
return r;
}
Py_complex
c_prod(Py_complex a, Py_complex b)
1996-01-11 20:47:05 -04:00
{
1996-07-20 23:31:35 -03:00
Py_complex r;
1996-01-11 20:47:05 -04:00
r.real = a.real*b.real - a.imag*b.imag;
r.imag = a.real*b.imag + a.imag*b.real;
return r;
}
Py_complex
c_quot(Py_complex a, Py_complex b)
1996-01-11 20:47:05 -04:00
{
/******************************************************************
This was the original algorithm. It's grossly prone to spurious
overflow and underflow errors. It also merrily divides by 0 despite
checking for that(!). The code still serves a doc purpose here, as
the algorithm following is a simple by-cases transformation of this
one:
1996-07-20 23:31:35 -03:00
Py_complex r;
1996-01-11 20:47:05 -04:00
double d = b.real*b.real + b.imag*b.imag;
if (d == 0.)
errno = EDOM;
1996-01-11 20:47:05 -04:00
r.real = (a.real*b.real + a.imag*b.imag)/d;
r.imag = (a.imag*b.real - a.real*b.imag)/d;
return r;
******************************************************************/
/* This algorithm is better, and is pretty obvious: first divide the
* numerators and denominator by whichever of {b.real, b.imag} has
* larger magnitude. The earliest reference I found was to CACM
* Algorithm 116 (Complex Division, Robert L. Smith, Stanford
* University). As usual, though, we're still ignoring all IEEE
* endcases.
*/
Py_complex r; /* the result */
const double abs_breal = b.real < 0 ? -b.real : b.real;
const double abs_bimag = b.imag < 0 ? -b.imag : b.imag;
if (abs_breal >= abs_bimag) {
/* divide tops and bottom by b.real */
if (abs_breal == 0.0) {
errno = EDOM;
r.real = r.imag = 0.0;
}
else {
const double ratio = b.imag / b.real;
const double denom = b.real + b.imag * ratio;
r.real = (a.real + a.imag * ratio) / denom;
r.imag = (a.imag - a.real * ratio) / denom;
}
}
else {
/* divide tops and bottom by b.imag */
const double ratio = b.real / b.imag;
const double denom = b.real * ratio + b.imag;
assert(b.imag != 0.0);
r.real = (a.real * ratio + a.imag) / denom;
r.imag = (a.imag * ratio - a.real) / denom;
}
return r;
1996-01-11 20:47:05 -04:00
}
Py_complex
c_pow(Py_complex a, Py_complex b)
1996-01-11 20:47:05 -04:00
{
1996-07-20 23:31:35 -03:00
Py_complex r;
1996-01-11 20:47:05 -04:00
double vabs,len,at,phase;
if (b.real == 0. && b.imag == 0.) {
r.real = 1.;
r.imag = 0.;
}
else if (a.real == 0. && a.imag == 0.) {
if (b.imag != 0. || b.real < 0.)
errno = ERANGE;
1996-01-11 20:47:05 -04:00
r.real = 0.;
r.imag = 0.;
}
else {
vabs = hypot(a.real,a.imag);
len = pow(vabs,b.real);
at = atan2(a.imag, a.real);
phase = at*b.real;
if (b.imag != 0.0) {
len /= exp(at*b.imag);
phase += b.imag*log(vabs);
}
r.real = len*cos(phase);
r.imag = len*sin(phase);
}
return r;
}
static Py_complex
c_powu(Py_complex x, long n)
1996-01-11 20:47:05 -04:00
{
Py_complex r, p;
1996-01-11 20:47:05 -04:00
long mask = 1;
r = c_1;
p = x;
1996-01-11 20:47:05 -04:00
while (mask > 0 && n >= mask) {
if (n & mask)
r = c_prod(r,p);
mask <<= 1;
p = c_prod(p,p);
}
return r;
}
static Py_complex
c_powi(Py_complex x, long n)
1996-01-11 20:47:05 -04:00
{
1996-07-20 23:31:35 -03:00
Py_complex cn;
1996-01-11 20:47:05 -04:00
if (n > 100 || n < -100) {
cn.real = (double) n;
cn.imag = 0.;
return c_pow(x,cn);
}
else if (n > 0)
return c_powu(x,n);
else
return c_quot(c_1,c_powu(x,-n));
}
PyObject *
2000-07-09 01:36:04 -03:00
PyComplex_FromCComplex(Py_complex cval)
1996-01-11 20:47:05 -04:00
{
register PyComplexObject *op;
/* PyObject_New is inlined */
op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject));
1996-01-11 20:47:05 -04:00
if (op == NULL)
1997-05-02 00:12:38 -03:00
return PyErr_NoMemory();
PyObject_INIT(op, &PyComplex_Type);
1996-01-11 20:47:05 -04:00
op->cval = cval;
1997-05-02 00:12:38 -03:00
return (PyObject *) op;
1996-01-11 20:47:05 -04:00
}
PyObject *
2000-07-09 01:36:04 -03:00
PyComplex_FromDoubles(double real, double imag)
{
Py_complex c;
c.real = real;
c.imag = imag;
return PyComplex_FromCComplex(c);
1996-01-11 20:47:05 -04:00
}
double
2000-07-09 01:36:04 -03:00
PyComplex_RealAsDouble(PyObject *op)
{
if (PyComplex_Check(op)) {
return ((PyComplexObject *)op)->cval.real;
2000-07-09 01:36:04 -03:00
}
else {
return PyFloat_AsDouble(op);
}
1996-01-11 20:47:05 -04:00
}
double
2000-07-09 01:36:04 -03:00
PyComplex_ImagAsDouble(PyObject *op)
{
if (PyComplex_Check(op)) {
return ((PyComplexObject *)op)->cval.imag;
2000-07-09 01:36:04 -03:00
}
else {
return 0.0;
}
1996-01-11 20:47:05 -04:00
}
1996-07-20 23:31:35 -03:00
Py_complex
2000-07-09 01:36:04 -03:00
PyComplex_AsCComplex(PyObject *op)
{
1996-07-20 23:31:35 -03:00
Py_complex cv;
1996-01-11 21:21:14 -04:00
if (PyComplex_Check(op)) {
return ((PyComplexObject *)op)->cval;
2000-07-09 01:36:04 -03:00
}
else {
1996-01-11 21:21:14 -04:00
cv.real = PyFloat_AsDouble(op);
cv.imag = 0.;
return cv;
}
1996-01-11 21:21:14 -04:00
}
1996-01-11 20:47:05 -04:00
static void
2000-07-09 01:36:04 -03:00
complex_dealloc(PyObject *op)
1996-01-11 20:47:05 -04:00
{
PyObject_DEL(op);
1996-01-11 20:47:05 -04:00
}
1996-05-24 17:45:01 -03:00
static void
complex_to_buf(char *buf, PyComplexObject *v, int precision)
1996-01-11 20:47:05 -04:00
{
if (v->cval.real == 0.)
sprintf(buf, "%.*gj", precision, v->cval.imag);
1996-01-11 20:47:05 -04:00
else
sprintf(buf, "(%.*g%+.*gj)", precision, v->cval.real,
precision, v->cval.imag);
1996-01-11 20:47:05 -04:00
}
static int
2000-07-09 01:36:04 -03:00
complex_print(PyComplexObject *v, FILE *fp, int flags)
1996-01-11 20:47:05 -04:00
{
char buf[100];
complex_to_buf(buf, v,
(flags & Py_PRINT_RAW) ? PREC_STR : PREC_REPR);
1996-01-11 20:47:05 -04:00
fputs(buf, fp);
return 0;
}
1997-05-02 00:12:38 -03:00
static PyObject *
2000-07-09 01:36:04 -03:00
complex_repr(PyComplexObject *v)
1996-01-11 20:47:05 -04:00
{
char buf[100];
complex_to_buf(buf, v, PREC_REPR);
return PyString_FromString(buf);
}
static PyObject *
complex_str(PyComplexObject *v)
{
char buf[100];
complex_to_buf(buf, v, PREC_STR);
1997-05-02 00:12:38 -03:00
return PyString_FromString(buf);
1996-01-11 20:47:05 -04:00
}
static long
2000-07-09 01:36:04 -03:00
complex_hash(PyComplexObject *v)
1996-01-11 20:47:05 -04:00
{
long hashreal, hashimag, combined;
hashreal = _Py_HashDouble(v->cval.real);
if (hashreal == -1)
return -1;
hashimag = _Py_HashDouble(v->cval.imag);
if (hashimag == -1)
return -1;
/* Note: if the imaginary part is 0, hashimag is 0 now,
* so the following returns hashreal unchanged. This is
* important because numbers of different types that
* compare equal must have the same hash value, so that
* hash(x + 0*j) must equal hash(x).
*/
combined = hashreal + 1000003 * hashimag;
if (combined == -1)
combined = -2;
return combined;
1996-01-11 20:47:05 -04:00
}
1997-05-02 00:12:38 -03:00
static PyObject *
2000-07-09 01:36:04 -03:00
complex_add(PyComplexObject *v, PyComplexObject *w)
1996-01-11 20:47:05 -04:00
{
Py_complex result;
PyFPE_START_PROTECT("complex_add", return 0)
result = c_sum(v->cval,w->cval);
1997-03-14 00:32:50 -04:00
PyFPE_END_PROTECT(result)
1997-05-02 00:12:38 -03:00
return PyComplex_FromCComplex(result);
1996-01-11 20:47:05 -04:00
}
1997-05-02 00:12:38 -03:00
static PyObject *
2000-07-09 01:36:04 -03:00
complex_sub(PyComplexObject *v, PyComplexObject *w)
1996-01-11 20:47:05 -04:00
{
Py_complex result;
PyFPE_START_PROTECT("complex_sub", return 0)
result = c_diff(v->cval,w->cval);
1997-03-14 00:32:50 -04:00
PyFPE_END_PROTECT(result)
1997-05-02 00:12:38 -03:00
return PyComplex_FromCComplex(result);
1996-01-11 20:47:05 -04:00
}
1997-05-02 00:12:38 -03:00
static PyObject *
2000-07-09 01:36:04 -03:00
complex_mul(PyComplexObject *v, PyComplexObject *w)
1996-01-11 20:47:05 -04:00
{
Py_complex result;
PyFPE_START_PROTECT("complex_mul", return 0)
result = c_prod(v->cval,w->cval);
1997-03-14 00:32:50 -04:00
PyFPE_END_PROTECT(result)
1997-05-02 00:12:38 -03:00
return PyComplex_FromCComplex(result);
1996-01-11 20:47:05 -04:00
}
1997-05-02 00:12:38 -03:00
static PyObject *
2000-07-09 01:36:04 -03:00
complex_div(PyComplexObject *v, PyComplexObject *w)
1996-01-11 20:47:05 -04:00
{
1996-07-20 23:31:35 -03:00
Py_complex quot;
PyFPE_START_PROTECT("complex_div", return 0)
errno = 0;
1996-01-11 20:47:05 -04:00
quot = c_quot(v->cval,w->cval);
1997-03-14 00:32:50 -04:00
PyFPE_END_PROTECT(quot)
if (errno == EDOM) {
1997-05-02 00:12:38 -03:00
PyErr_SetString(PyExc_ZeroDivisionError, "complex division");
1996-01-11 20:47:05 -04:00
return NULL;
}
1997-05-02 00:12:38 -03:00
return PyComplex_FromCComplex(quot);
1996-01-11 20:47:05 -04:00
}
1997-05-02 00:12:38 -03:00
static PyObject *
2000-07-09 01:36:04 -03:00
complex_remainder(PyComplexObject *v, PyComplexObject *w)
{
Py_complex div, mod;
errno = 0;
div = c_quot(v->cval,w->cval); /* The raw divisor value. */
if (errno == EDOM) {
1997-05-02 00:12:38 -03:00
PyErr_SetString(PyExc_ZeroDivisionError, "complex remainder");
return NULL;
}
div.real = floor(div.real); /* Use the floor of the real part. */
div.imag = 0.0;
mod = c_diff(v->cval, c_prod(w->cval, div));
1997-05-02 00:12:38 -03:00
return PyComplex_FromCComplex(mod);
}
1997-05-02 00:12:38 -03:00
static PyObject *
2000-07-09 01:36:04 -03:00
complex_divmod(PyComplexObject *v, PyComplexObject *w)
{
Py_complex div, mod;
PyObject *d, *m, *z;
errno = 0;
div = c_quot(v->cval,w->cval); /* The raw divisor value. */
if (errno == EDOM) {
1997-05-02 00:12:38 -03:00
PyErr_SetString(PyExc_ZeroDivisionError, "complex divmod()");
return NULL;
}
div.real = floor(div.real); /* Use the floor of the real part. */
div.imag = 0.0;
mod = c_diff(v->cval, c_prod(w->cval, div));
1997-05-02 00:12:38 -03:00
d = PyComplex_FromCComplex(div);
m = PyComplex_FromCComplex(mod);
z = Py_BuildValue("(OO)", d, m);
Py_XDECREF(d);
Py_XDECREF(m);
return z;
}
1996-01-11 20:47:05 -04:00
1997-05-02 00:12:38 -03:00
static PyObject *
2000-07-09 01:36:04 -03:00
complex_pow(PyComplexObject *v, PyObject *w, PyComplexObject *z)
1996-01-11 20:47:05 -04:00
{
1996-07-20 23:31:35 -03:00
Py_complex p;
Py_complex exponent;
1996-01-11 20:47:05 -04:00
long int_exponent;
1997-05-02 00:12:38 -03:00
if ((PyObject *)z!=Py_None) {
PyErr_SetString(PyExc_ValueError, "complex modulo");
1996-01-11 20:47:05 -04:00
return NULL;
}
PyFPE_START_PROTECT("complex_pow", return 0)
errno = 0;
1997-05-02 00:12:38 -03:00
exponent = ((PyComplexObject*)w)->cval;
1996-01-11 20:47:05 -04:00
int_exponent = (long)exponent.real;
if (exponent.imag == 0. && exponent.real == int_exponent)
p = c_powi(v->cval,int_exponent);
else
p = c_pow(v->cval,exponent);
1997-03-14 00:32:50 -04:00
PyFPE_END_PROTECT(p)
if (errno == ERANGE) {
1997-05-02 00:12:38 -03:00
PyErr_SetString(PyExc_ValueError,
"0.0 to a negative or complex power");
1996-01-11 20:47:05 -04:00
return NULL;
}
1997-05-02 00:12:38 -03:00
return PyComplex_FromCComplex(p);
1996-01-11 20:47:05 -04:00
}
1997-05-02 00:12:38 -03:00
static PyObject *
2000-07-09 01:36:04 -03:00
complex_neg(PyComplexObject *v)
1996-01-11 20:47:05 -04:00
{
1996-07-20 23:31:35 -03:00
Py_complex neg;
1996-01-11 20:47:05 -04:00
neg.real = -v->cval.real;
neg.imag = -v->cval.imag;
1997-05-02 00:12:38 -03:00
return PyComplex_FromCComplex(neg);
1996-01-11 20:47:05 -04:00
}
1997-05-02 00:12:38 -03:00
static PyObject *
2000-07-09 01:36:04 -03:00
complex_pos(PyComplexObject *v)
1996-01-11 20:47:05 -04:00
{
1997-05-02 00:12:38 -03:00
Py_INCREF(v);
return (PyObject *)v;
1996-01-11 20:47:05 -04:00
}
1997-05-02 00:12:38 -03:00
static PyObject *
2000-07-09 01:36:04 -03:00
complex_abs(PyComplexObject *v)
1996-01-11 20:47:05 -04:00
{
double result;
PyFPE_START_PROTECT("complex_abs", return 0)
result = hypot(v->cval.real,v->cval.imag);
1997-03-14 00:32:50 -04:00
PyFPE_END_PROTECT(result)
1997-05-02 00:12:38 -03:00
return PyFloat_FromDouble(result);
1996-01-11 20:47:05 -04:00
}
static int
2000-07-09 01:36:04 -03:00
complex_nonzero(PyComplexObject *v)
1996-01-11 20:47:05 -04:00
{
return v->cval.real != 0.0 || v->cval.imag != 0.0;
1996-01-11 20:47:05 -04:00
}
static int
2000-07-09 01:36:04 -03:00
complex_coerce(PyObject **pv, PyObject **pw)
1996-01-11 20:47:05 -04:00
{
1996-07-20 23:31:35 -03:00
Py_complex cval;
1996-01-11 20:47:05 -04:00
cval.imag = 0.;
1997-05-02 00:12:38 -03:00
if (PyInt_Check(*pw)) {
cval.real = (double)PyInt_AsLong(*pw);
*pw = PyComplex_FromCComplex(cval);
Py_INCREF(*pv);
1996-01-11 20:47:05 -04:00
return 0;
}
1997-05-02 00:12:38 -03:00
else if (PyLong_Check(*pw)) {
cval.real = PyLong_AsDouble(*pw);
*pw = PyComplex_FromCComplex(cval);
Py_INCREF(*pv);
1996-01-11 20:47:05 -04:00
return 0;
}
1997-05-02 00:12:38 -03:00
else if (PyFloat_Check(*pw)) {
cval.real = PyFloat_AsDouble(*pw);
*pw = PyComplex_FromCComplex(cval);
Py_INCREF(*pv);
1996-01-11 20:47:05 -04:00
return 0;
}
return 1; /* Can't do it */
}
static PyObject *
complex_richcompare(PyObject *v, PyObject *w, int op)
{
int c;
Py_complex i, j;
PyObject *res;
if (op != Py_EQ && op != Py_NE) {
PyErr_SetString(PyExc_TypeError,
"cannot compare complex numbers using <, <=, >, >=");
return NULL;
}
c = PyNumber_CoerceEx(&v, &w);
if (c < 0)
return NULL;
if (c > 0) {
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}
if (!PyComplex_Check(v) || !PyComplex_Check(w)) {
Py_DECREF(v);
Py_DECREF(w);
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}
i = ((PyComplexObject *)v)->cval;
j = ((PyComplexObject *)w)->cval;
Py_DECREF(v);
Py_DECREF(w);
if ((i.real == j.real && i.imag == j.imag) == (op == Py_EQ))
res = Py_True;
else
res = Py_False;
Py_INCREF(res);
return res;
}
1997-05-02 00:12:38 -03:00
static PyObject *
2000-07-09 01:36:04 -03:00
complex_int(PyObject *v)
1996-01-11 20:47:05 -04:00
{
1997-05-02 00:12:38 -03:00
PyErr_SetString(PyExc_TypeError,
"can't convert complex to int; use e.g. int(abs(z))");
return NULL;
1996-01-11 20:47:05 -04:00
}
1997-05-02 00:12:38 -03:00
static PyObject *
2000-07-09 01:36:04 -03:00
complex_long(PyObject *v)
1996-01-11 20:47:05 -04:00
{
1997-05-02 00:12:38 -03:00
PyErr_SetString(PyExc_TypeError,
"can't convert complex to long; use e.g. long(abs(z))");
return NULL;
1996-01-11 20:47:05 -04:00
}
1997-05-02 00:12:38 -03:00
static PyObject *
2000-07-09 01:36:04 -03:00
complex_float(PyObject *v)
1996-01-11 20:47:05 -04:00
{
1997-05-02 00:12:38 -03:00
PyErr_SetString(PyExc_TypeError,
"can't convert complex to float; use e.g. abs(z)");
return NULL;
1996-01-11 20:47:05 -04:00
}
1997-05-02 00:12:38 -03:00
static PyObject *
2000-07-09 01:36:04 -03:00
complex_conjugate(PyObject *self, PyObject *args)
1996-01-11 20:47:05 -04:00
{
Py_complex c;
if (!PyArg_ParseTuple(args, ":conjugate"))
return NULL;
1997-05-02 00:12:38 -03:00
c = ((PyComplexObject *)self)->cval;
1996-01-11 20:47:05 -04:00
c.imag = -c.imag;
1997-05-02 00:12:38 -03:00
return PyComplex_FromCComplex(c);
1996-01-11 20:47:05 -04:00
}
static PyMethodDef complex_methods[] = {
{"conjugate", complex_conjugate, 1},
1996-01-11 20:47:05 -04:00
{NULL, NULL} /* sentinel */
};
1997-05-02 00:12:38 -03:00
static PyObject *
2000-07-09 01:36:04 -03:00
complex_getattr(PyComplexObject *self, char *name)
1996-01-11 20:47:05 -04:00
{
if (strcmp(name, "real") == 0)
1997-05-02 00:12:38 -03:00
return (PyObject *)PyFloat_FromDouble(self->cval.real);
1996-01-11 20:47:05 -04:00
else if (strcmp(name, "imag") == 0)
1997-05-02 00:12:38 -03:00
return (PyObject *)PyFloat_FromDouble(self->cval.imag);
else if (strcmp(name, "__members__") == 0)
1997-05-02 00:12:38 -03:00
return Py_BuildValue("[ss]", "imag", "real");
return Py_FindMethod(complex_methods, (PyObject *)self, name);
1996-01-11 20:47:05 -04:00
}
1997-05-02 00:12:38 -03:00
static PyNumberMethods complex_as_number = {
(binaryfunc)complex_add, /* nb_add */
(binaryfunc)complex_sub, /* nb_subtract */
(binaryfunc)complex_mul, /* nb_multiply */
(binaryfunc)complex_div, /* nb_divide */
(binaryfunc)complex_remainder, /* nb_remainder */
(binaryfunc)complex_divmod, /* nb_divmod */
(ternaryfunc)complex_pow, /* nb_power */
(unaryfunc)complex_neg, /* nb_negative */
(unaryfunc)complex_pos, /* nb_positive */
(unaryfunc)complex_abs, /* nb_absolute */
(inquiry)complex_nonzero, /* nb_nonzero */
0, /* nb_invert */
0, /* nb_lshift */
0, /* nb_rshift */
0, /* nb_and */
0, /* nb_xor */
0, /* nb_or */
(coercion)complex_coerce, /* nb_coerce */
(unaryfunc)complex_int, /* nb_int */
(unaryfunc)complex_long, /* nb_long */
(unaryfunc)complex_float, /* nb_float */
0, /* nb_oct */
0, /* nb_hex */
1996-01-11 20:47:05 -04:00
};
1997-05-02 00:12:38 -03:00
PyTypeObject PyComplex_Type = {
PyObject_HEAD_INIT(&PyType_Type)
1996-01-11 20:47:05 -04:00
0,
"complex",
1997-05-02 00:12:38 -03:00
sizeof(PyComplexObject),
1996-01-11 20:47:05 -04:00
0,
(destructor)complex_dealloc, /* tp_dealloc */
(printfunc)complex_print, /* tp_print */
(getattrfunc)complex_getattr, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
(reprfunc)complex_repr, /* tp_repr */
&complex_as_number, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
(hashfunc)complex_hash, /* tp_hash */
0, /* tp_call */
(reprfunc)complex_str, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
complex_richcompare, /* tp_richcompare */
1996-01-11 20:47:05 -04:00
};
#endif