1997-05-20 15:21:34 -03:00
|
|
|
|
1996-01-11 20:47:05 -04:00
|
|
|
/* Complex object implementation */
|
|
|
|
|
|
|
|
/* Borrows heavily from floatobject.c */
|
|
|
|
|
1997-05-20 15:21:34 -03:00
|
|
|
/* Submitted by Jim Hugunin */
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
#include "Python.h"
|
2001-08-02 01:15:00 -03:00
|
|
|
#include "structmember.h"
|
1996-01-11 20:47:05 -04:00
|
|
|
|
2002-06-13 14:07:07 -03:00
|
|
|
#ifndef WITHOUT_COMPLEX
|
|
|
|
|
2001-03-11 04:37:29 -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.
|
|
|
|
*/
|
|
|
|
|
2010-05-09 11:46:46 -03:00
|
|
|
#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
|
|
|
|
2001-03-18 04:21:57 -04:00
|
|
|
Py_complex
|
|
|
|
c_sum(Py_complex a, Py_complex b)
|
1996-01-11 20:47:05 -04:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex r;
|
|
|
|
r.real = a.real + b.real;
|
|
|
|
r.imag = a.imag + b.imag;
|
|
|
|
return r;
|
1996-01-11 20:47:05 -04:00
|
|
|
}
|
|
|
|
|
2001-03-18 04:21:57 -04:00
|
|
|
Py_complex
|
|
|
|
c_diff(Py_complex a, Py_complex b)
|
1996-01-11 20:47:05 -04:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex r;
|
|
|
|
r.real = a.real - b.real;
|
|
|
|
r.imag = a.imag - b.imag;
|
|
|
|
return r;
|
1996-01-11 20:47:05 -04:00
|
|
|
}
|
|
|
|
|
2001-03-18 04:21:57 -04:00
|
|
|
Py_complex
|
|
|
|
c_neg(Py_complex a)
|
1996-01-11 20:47:05 -04:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex r;
|
|
|
|
r.real = -a.real;
|
|
|
|
r.imag = -a.imag;
|
|
|
|
return r;
|
1996-01-11 20:47:05 -04:00
|
|
|
}
|
|
|
|
|
2001-03-18 04:21:57 -04:00
|
|
|
Py_complex
|
|
|
|
c_prod(Py_complex a, Py_complex b)
|
1996-01-11 20:47:05 -04:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex r;
|
|
|
|
r.real = a.real*b.real - a.imag*b.imag;
|
|
|
|
r.imag = a.real*b.imag + a.imag*b.real;
|
|
|
|
return r;
|
1996-01-11 20:47:05 -04:00
|
|
|
}
|
|
|
|
|
2001-03-18 04:21:57 -04:00
|
|
|
Py_complex
|
|
|
|
c_quot(Py_complex a, Py_complex b)
|
1996-01-11 20:47:05 -04:00
|
|
|
{
|
2010-05-09 11:46:46 -03: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:
|
|
|
|
|
|
|
|
Py_complex r;
|
|
|
|
double d = b.real*b.real + b.imag*b.imag;
|
|
|
|
if (d == 0.)
|
|
|
|
errno = EDOM;
|
|
|
|
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;
|
|
|
|
|
2014-10-10 18:49:32 -03:00
|
|
|
if (abs_breal >= abs_bimag) {
|
2010-05-09 11:46:46 -03:00
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
}
|
2014-10-10 18:49:32 -03:00
|
|
|
else if (abs_bimag >= abs_breal) {
|
2010-05-09 11:46:46 -03:00
|
|
|
/* 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;
|
|
|
|
}
|
2014-10-10 18:49:32 -03:00
|
|
|
else {
|
|
|
|
/* At least one of b.real or b.imag is a NaN */
|
|
|
|
r.real = r.imag = Py_NAN;
|
|
|
|
}
|
2010-05-09 11:46:46 -03:00
|
|
|
return r;
|
1996-01-11 20:47:05 -04:00
|
|
|
}
|
|
|
|
|
2001-03-18 04:21:57 -04:00
|
|
|
Py_complex
|
|
|
|
c_pow(Py_complex a, Py_complex b)
|
1996-01-11 20:47:05 -04:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex r;
|
|
|
|
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 = EDOM;
|
|
|
|
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;
|
1996-01-11 20:47:05 -04:00
|
|
|
}
|
|
|
|
|
2001-03-18 04:21:57 -04:00
|
|
|
static Py_complex
|
|
|
|
c_powu(Py_complex x, long n)
|
1996-01-11 20:47:05 -04:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex r, p;
|
|
|
|
long mask = 1;
|
|
|
|
r = c_1;
|
|
|
|
p = x;
|
|
|
|
while (mask > 0 && n >= mask) {
|
|
|
|
if (n & mask)
|
|
|
|
r = c_prod(r,p);
|
|
|
|
mask <<= 1;
|
|
|
|
p = c_prod(p,p);
|
|
|
|
}
|
|
|
|
return r;
|
1996-01-11 20:47:05 -04:00
|
|
|
}
|
|
|
|
|
2001-03-18 04:21:57 -04:00
|
|
|
static Py_complex
|
|
|
|
c_powi(Py_complex x, long n)
|
1996-01-11 20:47:05 -04:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex cn;
|
|
|
|
|
|
|
|
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));
|
1996-01-11 20:47:05 -04:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2008-04-18 20:13:07 -03:00
|
|
|
double
|
|
|
|
c_abs(Py_complex z)
|
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
/* sets errno = ERANGE on overflow; otherwise errno = 0 */
|
|
|
|
double result;
|
|
|
|
|
|
|
|
if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) {
|
|
|
|
/* C99 rules: if either the real or the imaginary part is an
|
|
|
|
infinity, return infinity, even if the other part is a
|
|
|
|
NaN. */
|
|
|
|
if (Py_IS_INFINITY(z.real)) {
|
|
|
|
result = fabs(z.real);
|
|
|
|
errno = 0;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
if (Py_IS_INFINITY(z.imag)) {
|
|
|
|
result = fabs(z.imag);
|
|
|
|
errno = 0;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
/* either the real or imaginary part is a NaN,
|
|
|
|
and neither is infinite. Result should be NaN. */
|
|
|
|
return Py_NAN;
|
|
|
|
}
|
|
|
|
result = hypot(z.real, z.imag);
|
|
|
|
if (!Py_IS_FINITE(result))
|
|
|
|
errno = ERANGE;
|
|
|
|
else
|
|
|
|
errno = 0;
|
|
|
|
return result;
|
2008-04-18 20:13:07 -03:00
|
|
|
}
|
|
|
|
|
2001-08-02 01:15:00 -03:00
|
|
|
static PyObject *
|
|
|
|
complex_subtype_from_c_complex(PyTypeObject *type, Py_complex cval)
|
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
PyObject *op;
|
2001-08-02 01:15:00 -03:00
|
|
|
|
2010-05-09 11:46:46 -03:00
|
|
|
op = type->tp_alloc(type, 0);
|
|
|
|
if (op != NULL)
|
|
|
|
((PyComplexObject *)op)->cval = cval;
|
|
|
|
return op;
|
2001-08-02 01:15:00 -03:00
|
|
|
}
|
|
|
|
|
1996-01-11 20:47:05 -04:00
|
|
|
PyObject *
|
2000-07-09 01:36:04 -03:00
|
|
|
PyComplex_FromCComplex(Py_complex cval)
|
1996-01-11 20:47:05 -04:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
register PyComplexObject *op;
|
|
|
|
|
|
|
|
/* Inline PyObject_New */
|
|
|
|
op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject));
|
|
|
|
if (op == NULL)
|
|
|
|
return PyErr_NoMemory();
|
2016-06-21 20:58:05 -03:00
|
|
|
(void)PyObject_INIT(op, &PyComplex_Type);
|
2010-05-09 11:46:46 -03:00
|
|
|
op->cval = cval;
|
|
|
|
return (PyObject *) op;
|
1996-01-11 20:47:05 -04:00
|
|
|
}
|
|
|
|
|
2001-08-02 01:15:00 -03:00
|
|
|
static PyObject *
|
|
|
|
complex_subtype_from_doubles(PyTypeObject *type, double real, double imag)
|
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex c;
|
|
|
|
c.real = real;
|
|
|
|
c.imag = imag;
|
|
|
|
return complex_subtype_from_c_complex(type, c);
|
2001-08-02 01:15:00 -03:00
|
|
|
}
|
|
|
|
|
1996-01-11 20:47:05 -04:00
|
|
|
PyObject *
|
2000-07-09 01:36:04 -03:00
|
|
|
PyComplex_FromDoubles(double real, double imag)
|
1996-08-19 16:30:45 -03:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
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)
|
1996-08-19 16:30:45 -03:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
if (PyComplex_Check(op)) {
|
|
|
|
return ((PyComplexObject *)op)->cval.real;
|
|
|
|
}
|
|
|
|
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)
|
1996-08-19 16:30:45 -03:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
if (PyComplex_Check(op)) {
|
|
|
|
return ((PyComplexObject *)op)->cval.imag;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return 0.0;
|
|
|
|
}
|
1996-01-11 20:47:05 -04:00
|
|
|
}
|
|
|
|
|
2010-01-03 21:00:47 -04:00
|
|
|
static PyObject *
|
|
|
|
try_complex_special_method(PyObject *op) {
|
2010-05-09 11:46:46 -03:00
|
|
|
PyObject *f;
|
|
|
|
static PyObject *complexstr;
|
|
|
|
|
|
|
|
if (complexstr == NULL) {
|
|
|
|
complexstr = PyString_InternFromString("__complex__");
|
|
|
|
if (complexstr == NULL)
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (PyInstance_Check(op)) {
|
|
|
|
f = PyObject_GetAttr(op, complexstr);
|
|
|
|
if (f == NULL) {
|
|
|
|
if (PyErr_ExceptionMatches(PyExc_AttributeError))
|
|
|
|
PyErr_Clear();
|
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
f = _PyObject_LookupSpecial(op, "__complex__", &complexstr);
|
|
|
|
if (f == NULL && PyErr_Occurred())
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (f != NULL) {
|
|
|
|
PyObject *res = PyObject_CallFunctionObjArgs(f, NULL);
|
|
|
|
Py_DECREF(f);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
return NULL;
|
2010-01-03 21:00:47 -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-08-19 16:30:45 -03:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex cv;
|
|
|
|
PyObject *newop = NULL;
|
|
|
|
|
|
|
|
assert(op);
|
|
|
|
/* If op is already of type PyComplex_Type, return its value */
|
|
|
|
if (PyComplex_Check(op)) {
|
|
|
|
return ((PyComplexObject *)op)->cval;
|
|
|
|
}
|
|
|
|
/* If not, use op's __complex__ method, if it exists */
|
|
|
|
|
|
|
|
/* return -1 on failure */
|
|
|
|
cv.real = -1.;
|
|
|
|
cv.imag = 0.;
|
|
|
|
|
|
|
|
newop = try_complex_special_method(op);
|
|
|
|
|
|
|
|
if (newop) {
|
|
|
|
if (!PyComplex_Check(newop)) {
|
|
|
|
PyErr_SetString(PyExc_TypeError,
|
|
|
|
"__complex__ should return a complex object");
|
|
|
|
Py_DECREF(newop);
|
|
|
|
return cv;
|
|
|
|
}
|
|
|
|
cv = ((PyComplexObject *)newop)->cval;
|
|
|
|
Py_DECREF(newop);
|
|
|
|
return cv;
|
|
|
|
}
|
|
|
|
else if (PyErr_Occurred()) {
|
|
|
|
return cv;
|
|
|
|
}
|
|
|
|
/* If neither of the above works, interpret op as a float giving the
|
|
|
|
real part of the result, and fill in the imaginary part as 0. */
|
|
|
|
else {
|
|
|
|
/* PyFloat_AsDouble will return -1 on failure */
|
|
|
|
cv.real = PyFloat_AsDouble(op);
|
|
|
|
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
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
op->ob_type->tp_free(op);
|
1996-01-11 20:47:05 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-24 09:46:53 -03:00
|
|
|
static PyObject *
|
2009-05-05 15:26:08 -03:00
|
|
|
complex_format(PyComplexObject *v, int precision, char format_code)
|
1996-01-11 20:47:05 -04:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
PyObject *result = NULL;
|
|
|
|
Py_ssize_t len;
|
|
|
|
|
|
|
|
/* If these are non-NULL, they'll need to be freed. */
|
|
|
|
char *pre = NULL;
|
|
|
|
char *im = NULL;
|
|
|
|
char *buf = NULL;
|
|
|
|
|
|
|
|
/* These do not need to be freed. re is either an alias
|
|
|
|
for pre or a pointer to a constant. lead and tail
|
|
|
|
are pointers to constants. */
|
|
|
|
char *re = NULL;
|
|
|
|
char *lead = "";
|
|
|
|
char *tail = "";
|
|
|
|
|
|
|
|
if (v->cval.real == 0. && copysign(1.0, v->cval.real)==1.0) {
|
|
|
|
re = "";
|
|
|
|
im = PyOS_double_to_string(v->cval.imag, format_code,
|
|
|
|
precision, 0, NULL);
|
|
|
|
if (!im) {
|
|
|
|
PyErr_NoMemory();
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* Format imaginary part with sign, real part without */
|
|
|
|
pre = PyOS_double_to_string(v->cval.real, format_code,
|
|
|
|
precision, 0, NULL);
|
|
|
|
if (!pre) {
|
|
|
|
PyErr_NoMemory();
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
re = pre;
|
|
|
|
|
|
|
|
im = PyOS_double_to_string(v->cval.imag, format_code,
|
|
|
|
precision, Py_DTSF_SIGN, NULL);
|
|
|
|
if (!im) {
|
|
|
|
PyErr_NoMemory();
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
lead = "(";
|
|
|
|
tail = ")";
|
|
|
|
}
|
|
|
|
/* Alloc the final buffer. Add one for the "j" in the format string,
|
|
|
|
and one for the trailing zero. */
|
|
|
|
len = strlen(lead) + strlen(re) + strlen(im) + strlen(tail) + 2;
|
|
|
|
buf = PyMem_Malloc(len);
|
|
|
|
if (!buf) {
|
|
|
|
PyErr_NoMemory();
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
PyOS_snprintf(buf, len, "%s%s%sj%s", lead, re, im, tail);
|
|
|
|
result = PyString_FromString(buf);
|
2009-04-24 09:46:53 -03:00
|
|
|
done:
|
2010-05-09 11:46:46 -03:00
|
|
|
PyMem_Free(im);
|
|
|
|
PyMem_Free(pre);
|
|
|
|
PyMem_Free(buf);
|
2009-04-24 09:46:53 -03:00
|
|
|
|
2010-05-09 11:46:46 -03:00
|
|
|
return result;
|
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
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
PyObject *formatv;
|
|
|
|
char *buf;
|
|
|
|
if (flags & Py_PRINT_RAW)
|
|
|
|
formatv = complex_format(v, PyFloat_STR_PRECISION, 'g');
|
|
|
|
else
|
|
|
|
formatv = complex_format(v, 0, 'r');
|
|
|
|
if (formatv == NULL)
|
|
|
|
return -1;
|
|
|
|
buf = PyString_AS_STRING(formatv);
|
|
|
|
Py_BEGIN_ALLOW_THREADS
|
|
|
|
fputs(buf, fp);
|
|
|
|
Py_END_ALLOW_THREADS
|
|
|
|
Py_DECREF(formatv);
|
|
|
|
return 0;
|
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_repr(PyComplexObject *v)
|
1996-01-11 20:47:05 -04:00
|
|
|
{
|
2009-05-05 15:26:08 -03:00
|
|
|
return complex_format(v, 0, 'r');
|
2001-03-11 04:37:29 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
complex_str(PyComplexObject *v)
|
|
|
|
{
|
2009-05-05 15:26:08 -03:00
|
|
|
return complex_format(v, PyFloat_STR_PRECISION, 'g');
|
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
|
|
|
{
|
2010-05-09 11:46:46 -03: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
|
|
|
}
|
|
|
|
|
Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
the complex_pow part), r56649, r56652, r56715, r57296, r57302, r57359, r57361,
r57372, r57738, r57739, r58017, r58039, r58040, and r59390, and new
documentation. The only significant difference is that round(x) returns a float
to preserve backward-compatibility. See http://bugs.python.org/issue1689.
2008-01-02 22:21:52 -04:00
|
|
|
/* This macro may return! */
|
|
|
|
#define TO_COMPLEX(obj, c) \
|
2010-05-09 11:46:46 -03:00
|
|
|
if (PyComplex_Check(obj)) \
|
|
|
|
c = ((PyComplexObject *)(obj))->cval; \
|
|
|
|
else if (to_complex(&(obj), &(c)) < 0) \
|
|
|
|
return (obj)
|
Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
the complex_pow part), r56649, r56652, r56715, r57296, r57302, r57359, r57361,
r57372, r57738, r57739, r58017, r58039, r58040, and r59390, and new
documentation. The only significant difference is that round(x) returns a float
to preserve backward-compatibility. See http://bugs.python.org/issue1689.
2008-01-02 22:21:52 -04:00
|
|
|
|
|
|
|
static int
|
|
|
|
to_complex(PyObject **pobj, Py_complex *pc)
|
|
|
|
{
|
|
|
|
PyObject *obj = *pobj;
|
|
|
|
|
|
|
|
pc->real = pc->imag = 0.0;
|
|
|
|
if (PyInt_Check(obj)) {
|
2010-05-09 11:46:46 -03:00
|
|
|
pc->real = PyInt_AS_LONG(obj);
|
|
|
|
return 0;
|
Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
the complex_pow part), r56649, r56652, r56715, r57296, r57302, r57359, r57361,
r57372, r57738, r57739, r58017, r58039, r58040, and r59390, and new
documentation. The only significant difference is that round(x) returns a float
to preserve backward-compatibility. See http://bugs.python.org/issue1689.
2008-01-02 22:21:52 -04:00
|
|
|
}
|
|
|
|
if (PyLong_Check(obj)) {
|
2010-05-09 11:46:46 -03:00
|
|
|
pc->real = PyLong_AsDouble(obj);
|
|
|
|
if (pc->real == -1.0 && PyErr_Occurred()) {
|
|
|
|
*pobj = NULL;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
the complex_pow part), r56649, r56652, r56715, r57296, r57302, r57359, r57361,
r57372, r57738, r57739, r58017, r58039, r58040, and r59390, and new
documentation. The only significant difference is that round(x) returns a float
to preserve backward-compatibility. See http://bugs.python.org/issue1689.
2008-01-02 22:21:52 -04:00
|
|
|
}
|
|
|
|
if (PyFloat_Check(obj)) {
|
2010-05-09 11:46:46 -03:00
|
|
|
pc->real = PyFloat_AsDouble(obj);
|
|
|
|
return 0;
|
Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
the complex_pow part), r56649, r56652, r56715, r57296, r57302, r57359, r57361,
r57372, r57738, r57739, r58017, r58039, r58040, and r59390, and new
documentation. The only significant difference is that round(x) returns a float
to preserve backward-compatibility. See http://bugs.python.org/issue1689.
2008-01-02 22:21:52 -04:00
|
|
|
}
|
|
|
|
Py_INCREF(Py_NotImplemented);
|
|
|
|
*pobj = Py_NotImplemented;
|
|
|
|
return -1;
|
|
|
|
}
|
2010-05-09 11:46:46 -03:00
|
|
|
|
Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
the complex_pow part), r56649, r56652, r56715, r57296, r57302, r57359, r57361,
r57372, r57738, r57739, r58017, r58039, r58040, and r59390, and new
documentation. The only significant difference is that round(x) returns a float
to preserve backward-compatibility. See http://bugs.python.org/issue1689.
2008-01-02 22:21:52 -04:00
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2010-02-21 08:57:35 -04:00
|
|
|
complex_add(PyObject *v, PyObject *w)
|
1996-01-11 20:47:05 -04:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex result;
|
|
|
|
Py_complex a, b;
|
|
|
|
TO_COMPLEX(v, a);
|
|
|
|
TO_COMPLEX(w, b);
|
|
|
|
PyFPE_START_PROTECT("complex_add", return 0)
|
|
|
|
result = c_sum(a, b);
|
|
|
|
PyFPE_END_PROTECT(result)
|
|
|
|
return PyComplex_FromCComplex(result);
|
1996-01-11 20:47:05 -04:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2010-02-21 08:57:35 -04:00
|
|
|
complex_sub(PyObject *v, PyObject *w)
|
1996-01-11 20:47:05 -04:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex result;
|
|
|
|
Py_complex a, b;
|
|
|
|
TO_COMPLEX(v, a);
|
|
|
|
TO_COMPLEX(w, b);;
|
|
|
|
PyFPE_START_PROTECT("complex_sub", return 0)
|
|
|
|
result = c_diff(a, b);
|
|
|
|
PyFPE_END_PROTECT(result)
|
|
|
|
return PyComplex_FromCComplex(result);
|
1996-01-11 20:47:05 -04:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2010-02-21 08:57:35 -04:00
|
|
|
complex_mul(PyObject *v, PyObject *w)
|
1996-01-11 20:47:05 -04:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex result;
|
|
|
|
Py_complex a, b;
|
|
|
|
TO_COMPLEX(v, a);
|
|
|
|
TO_COMPLEX(w, b);
|
|
|
|
PyFPE_START_PROTECT("complex_mul", return 0)
|
|
|
|
result = c_prod(a, b);
|
|
|
|
PyFPE_END_PROTECT(result)
|
|
|
|
return PyComplex_FromCComplex(result);
|
1996-01-11 20:47:05 -04:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2010-02-21 08:57:35 -04:00
|
|
|
complex_div(PyObject *v, PyObject *w)
|
1996-01-11 20:47:05 -04:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex quot;
|
|
|
|
Py_complex a, b;
|
|
|
|
TO_COMPLEX(v, a);
|
|
|
|
TO_COMPLEX(w, b);
|
|
|
|
PyFPE_START_PROTECT("complex_div", return 0)
|
|
|
|
errno = 0;
|
|
|
|
quot = c_quot(a, b);
|
|
|
|
PyFPE_END_PROTECT(quot)
|
|
|
|
if (errno == EDOM) {
|
|
|
|
PyErr_SetString(PyExc_ZeroDivisionError, "complex division by zero");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return PyComplex_FromCComplex(quot);
|
1996-01-11 20:47:05 -04:00
|
|
|
}
|
|
|
|
|
Add warning mode for classic division, almost exactly as specified in
PEP 238. Changes:
- add a new flag variable Py_DivisionWarningFlag, declared in
pydebug.h, defined in object.c, set in main.c, and used in
{int,long,float,complex}object.c. When this flag is set, the
classic division operator issues a DeprecationWarning message.
- add a new API PyRun_SimpleStringFlags() to match
PyRun_SimpleString(). The main() function calls this so that
commands run with -c can also benefit from -Dnew.
- While I was at it, I changed the usage message in main() somewhat:
alphabetized the options, split it in *four* parts to fit in under
512 bytes (not that I still believe this is necessary -- doc strings
elsewhere are much longer), and perhaps most visibly, don't display
the full list of options on each command line error. Instead, the
full list is only displayed when -h is used, and otherwise a brief
reminder of -h is displayed. When -h is used, write to stdout so
that you can do `python -h | more'.
Notes:
- I don't want to use the -W option to control whether the classic
division warning is issued or not, because the machinery to decide
whether to display the warning or not is very expensive (it involves
calling into the warnings.py module). You can use -Werror to turn
the warnings into exceptions though.
- The -Dnew option doesn't select future division for all of the
program -- only for the __main__ module. I don't know if I'll ever
change this -- it would require changes to the .pyc file magic
number to do it right, and a more global notion of compiler flags.
- You can usefully combine -Dwarn and -Dnew: this gives the __main__
module new division, and warns about classic division everywhere
else.
2001-08-31 14:40:15 -03:00
|
|
|
static PyObject *
|
2010-02-21 08:57:35 -04:00
|
|
|
complex_classic_div(PyObject *v, PyObject *w)
|
Add warning mode for classic division, almost exactly as specified in
PEP 238. Changes:
- add a new flag variable Py_DivisionWarningFlag, declared in
pydebug.h, defined in object.c, set in main.c, and used in
{int,long,float,complex}object.c. When this flag is set, the
classic division operator issues a DeprecationWarning message.
- add a new API PyRun_SimpleStringFlags() to match
PyRun_SimpleString(). The main() function calls this so that
commands run with -c can also benefit from -Dnew.
- While I was at it, I changed the usage message in main() somewhat:
alphabetized the options, split it in *four* parts to fit in under
512 bytes (not that I still believe this is necessary -- doc strings
elsewhere are much longer), and perhaps most visibly, don't display
the full list of options on each command line error. Instead, the
full list is only displayed when -h is used, and otherwise a brief
reminder of -h is displayed. When -h is used, write to stdout so
that you can do `python -h | more'.
Notes:
- I don't want to use the -W option to control whether the classic
division warning is issued or not, because the machinery to decide
whether to display the warning or not is very expensive (it involves
calling into the warnings.py module). You can use -Werror to turn
the warnings into exceptions though.
- The -Dnew option doesn't select future division for all of the
program -- only for the __main__ module. I don't know if I'll ever
change this -- it would require changes to the .pyc file magic
number to do it right, and a more global notion of compiler flags.
- You can usefully combine -Dwarn and -Dnew: this gives the __main__
module new division, and warns about classic division everywhere
else.
2001-08-31 14:40:15 -03:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex quot;
|
|
|
|
Py_complex a, b;
|
|
|
|
TO_COMPLEX(v, a);
|
|
|
|
TO_COMPLEX(w, b);
|
|
|
|
if (Py_DivisionWarningFlag >= 2 &&
|
|
|
|
PyErr_Warn(PyExc_DeprecationWarning,
|
|
|
|
"classic complex division") < 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
PyFPE_START_PROTECT("complex_classic_div", return 0)
|
|
|
|
errno = 0;
|
|
|
|
quot = c_quot(a, b);
|
|
|
|
PyFPE_END_PROTECT(quot)
|
|
|
|
if (errno == EDOM) {
|
|
|
|
PyErr_SetString(PyExc_ZeroDivisionError, "complex division by zero");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return PyComplex_FromCComplex(quot);
|
Add warning mode for classic division, almost exactly as specified in
PEP 238. Changes:
- add a new flag variable Py_DivisionWarningFlag, declared in
pydebug.h, defined in object.c, set in main.c, and used in
{int,long,float,complex}object.c. When this flag is set, the
classic division operator issues a DeprecationWarning message.
- add a new API PyRun_SimpleStringFlags() to match
PyRun_SimpleString(). The main() function calls this so that
commands run with -c can also benefit from -Dnew.
- While I was at it, I changed the usage message in main() somewhat:
alphabetized the options, split it in *four* parts to fit in under
512 bytes (not that I still believe this is necessary -- doc strings
elsewhere are much longer), and perhaps most visibly, don't display
the full list of options on each command line error. Instead, the
full list is only displayed when -h is used, and otherwise a brief
reminder of -h is displayed. When -h is used, write to stdout so
that you can do `python -h | more'.
Notes:
- I don't want to use the -W option to control whether the classic
division warning is issued or not, because the machinery to decide
whether to display the warning or not is very expensive (it involves
calling into the warnings.py module). You can use -Werror to turn
the warnings into exceptions though.
- The -Dnew option doesn't select future division for all of the
program -- only for the __main__ module. I don't know if I'll ever
change this -- it would require changes to the .pyc file magic
number to do it right, and a more global notion of compiler flags.
- You can usefully combine -Dwarn and -Dnew: this gives the __main__
module new division, and warns about classic division everywhere
else.
2001-08-31 14:40:15 -03:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2010-02-21 08:57:35 -04:00
|
|
|
complex_remainder(PyObject *v, PyObject *w)
|
1996-09-11 10:55:55 -03:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex div, mod;
|
|
|
|
Py_complex a, b;
|
|
|
|
TO_COMPLEX(v, a);
|
|
|
|
TO_COMPLEX(w, b);
|
|
|
|
if (PyErr_Warn(PyExc_DeprecationWarning,
|
|
|
|
"complex divmod(), // and % are deprecated") < 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
errno = 0;
|
|
|
|
div = c_quot(a, b); /* The raw divisor value. */
|
|
|
|
if (errno == EDOM) {
|
|
|
|
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(a, c_prod(b, div));
|
|
|
|
|
|
|
|
return PyComplex_FromCComplex(mod);
|
1996-09-11 10:55:55 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2010-02-21 08:57:35 -04:00
|
|
|
complex_divmod(PyObject *v, PyObject *w)
|
1996-09-12 17:56:18 -03:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex div, mod;
|
|
|
|
PyObject *d, *m, *z;
|
|
|
|
Py_complex a, b;
|
|
|
|
TO_COMPLEX(v, a);
|
|
|
|
TO_COMPLEX(w, b);
|
|
|
|
if (PyErr_Warn(PyExc_DeprecationWarning,
|
|
|
|
"complex divmod(), // and % are deprecated") < 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
errno = 0;
|
|
|
|
div = c_quot(a, b); /* The raw divisor value. */
|
|
|
|
if (errno == EDOM) {
|
|
|
|
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(a, c_prod(b, div));
|
|
|
|
d = PyComplex_FromCComplex(div);
|
|
|
|
m = PyComplex_FromCComplex(mod);
|
|
|
|
z = PyTuple_Pack(2, d, m);
|
|
|
|
Py_XDECREF(d);
|
|
|
|
Py_XDECREF(m);
|
|
|
|
return z;
|
1996-09-12 17:56:18 -03:00
|
|
|
}
|
1996-01-11 20:47:05 -04:00
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
the complex_pow part), r56649, r56652, r56715, r57296, r57302, r57359, r57361,
r57372, r57738, r57739, r58017, r58039, r58040, and r59390, and new
documentation. The only significant difference is that round(x) returns a float
to preserve backward-compatibility. See http://bugs.python.org/issue1689.
2008-01-02 22:21:52 -04:00
|
|
|
complex_pow(PyObject *v, PyObject *w, PyObject *z)
|
1996-01-11 20:47:05 -04:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex p;
|
|
|
|
Py_complex exponent;
|
|
|
|
long int_exponent;
|
|
|
|
Py_complex a, b;
|
|
|
|
TO_COMPLEX(v, a);
|
|
|
|
TO_COMPLEX(w, b);
|
|
|
|
if (z!=Py_None) {
|
|
|
|
PyErr_SetString(PyExc_ValueError, "complex modulo");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
PyFPE_START_PROTECT("complex_pow", return 0)
|
|
|
|
errno = 0;
|
|
|
|
exponent = b;
|
|
|
|
int_exponent = (long)exponent.real;
|
|
|
|
if (exponent.imag == 0. && exponent.real == int_exponent)
|
|
|
|
p = c_powi(a,int_exponent);
|
|
|
|
else
|
|
|
|
p = c_pow(a,exponent);
|
|
|
|
|
|
|
|
PyFPE_END_PROTECT(p)
|
|
|
|
Py_ADJUST_ERANGE2(p.real, p.imag);
|
|
|
|
if (errno == EDOM) {
|
|
|
|
PyErr_SetString(PyExc_ZeroDivisionError,
|
|
|
|
"0.0 to a negative or complex power");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
else if (errno == ERANGE) {
|
|
|
|
PyErr_SetString(PyExc_OverflowError,
|
|
|
|
"complex exponentiation");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return PyComplex_FromCComplex(p);
|
1996-01-11 20:47:05 -04:00
|
|
|
}
|
|
|
|
|
2001-08-08 02:00:18 -03:00
|
|
|
static PyObject *
|
2010-02-21 08:57:35 -04:00
|
|
|
complex_int_div(PyObject *v, PyObject *w)
|
2001-08-08 02:00:18 -03:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
PyObject *t, *r;
|
|
|
|
Py_complex a, b;
|
|
|
|
TO_COMPLEX(v, a);
|
|
|
|
TO_COMPLEX(w, b);
|
|
|
|
if (PyErr_Warn(PyExc_DeprecationWarning,
|
|
|
|
"complex divmod(), // and % are deprecated") < 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
t = complex_divmod(v, w);
|
|
|
|
if (t != NULL) {
|
|
|
|
r = PyTuple_GET_ITEM(t, 0);
|
|
|
|
Py_INCREF(r);
|
|
|
|
Py_DECREF(t);
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
return NULL;
|
2001-08-08 02:00:18 -03: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
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex neg;
|
|
|
|
neg.real = -v->cval.real;
|
|
|
|
neg.imag = -v->cval.imag;
|
|
|
|
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
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
if (PyComplex_CheckExact(v)) {
|
|
|
|
Py_INCREF(v);
|
|
|
|
return (PyObject *)v;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return PyComplex_FromCComplex(v->cval);
|
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
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
double result;
|
|
|
|
|
|
|
|
PyFPE_START_PROTECT("complex_abs", return 0)
|
|
|
|
result = c_abs(v->cval);
|
|
|
|
PyFPE_END_PROTECT(result)
|
|
|
|
|
|
|
|
if (errno == ERANGE) {
|
|
|
|
PyErr_SetString(PyExc_OverflowError,
|
|
|
|
"absolute value too large");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
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
|
|
|
{
|
2010-05-09 11:46:46 -03: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
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex cval;
|
|
|
|
cval.imag = 0.;
|
|
|
|
if (PyInt_Check(*pw)) {
|
|
|
|
cval.real = (double)PyInt_AsLong(*pw);
|
|
|
|
*pw = PyComplex_FromCComplex(cval);
|
|
|
|
Py_INCREF(*pv);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else if (PyLong_Check(*pw)) {
|
|
|
|
cval.real = PyLong_AsDouble(*pw);
|
|
|
|
if (cval.real == -1.0 && PyErr_Occurred())
|
|
|
|
return -1;
|
|
|
|
*pw = PyComplex_FromCComplex(cval);
|
|
|
|
Py_INCREF(*pv);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else if (PyFloat_Check(*pw)) {
|
|
|
|
cval.real = PyFloat_AsDouble(*pw);
|
|
|
|
*pw = PyComplex_FromCComplex(cval);
|
|
|
|
Py_INCREF(*pv);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else if (PyComplex_Check(*pw)) {
|
|
|
|
Py_INCREF(*pv);
|
|
|
|
Py_INCREF(*pw);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1; /* Can't do it */
|
1996-01-11 20:47:05 -04:00
|
|
|
}
|
|
|
|
|
2001-01-17 21:12:39 -04:00
|
|
|
static PyObject *
|
|
|
|
complex_richcompare(PyObject *v, PyObject *w, int op)
|
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
PyObject *res;
|
2010-05-30 10:18:10 -03:00
|
|
|
Py_complex i;
|
|
|
|
int equal;
|
2010-05-09 11:46:46 -03:00
|
|
|
|
2010-05-30 10:18:10 -03:00
|
|
|
if (op != Py_EQ && op != Py_NE) {
|
|
|
|
/* for backwards compatibility, comparisons with non-numbers return
|
|
|
|
* NotImplemented. Only comparisons with core numeric types raise
|
|
|
|
* TypeError.
|
|
|
|
*/
|
|
|
|
if (PyInt_Check(w) || PyLong_Check(w) ||
|
|
|
|
PyFloat_Check(w) || PyComplex_Check(w)) {
|
|
|
|
PyErr_SetString(PyExc_TypeError,
|
|
|
|
"no ordering relation is defined "
|
|
|
|
"for complex numbers");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
goto Unimplemented;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(PyComplex_Check(v));
|
2010-05-30 09:12:25 -03:00
|
|
|
TO_COMPLEX(v, i);
|
2010-05-09 11:46:46 -03:00
|
|
|
|
2010-05-30 10:18:10 -03:00
|
|
|
if (PyInt_Check(w) || PyLong_Check(w)) {
|
|
|
|
/* Check for 0.0 imaginary part first to avoid the rich
|
|
|
|
* comparison when possible.
|
|
|
|
*/
|
|
|
|
if (i.imag == 0.0) {
|
|
|
|
PyObject *j, *sub_res;
|
|
|
|
j = PyFloat_FromDouble(i.real);
|
|
|
|
if (j == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
sub_res = PyObject_RichCompare(j, w, op);
|
|
|
|
Py_DECREF(j);
|
|
|
|
return sub_res;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
equal = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (PyFloat_Check(w)) {
|
|
|
|
equal = (i.real == PyFloat_AsDouble(w) && i.imag == 0.0);
|
|
|
|
}
|
|
|
|
else if (PyComplex_Check(w)) {
|
|
|
|
Py_complex j;
|
|
|
|
|
|
|
|
TO_COMPLEX(w, j);
|
|
|
|
equal = (i.real == j.real && i.imag == j.imag);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
goto Unimplemented;
|
2010-05-09 11:46:46 -03:00
|
|
|
}
|
|
|
|
|
2010-05-30 10:18:10 -03:00
|
|
|
if (equal == (op == Py_EQ))
|
|
|
|
res = Py_True;
|
2010-05-09 11:46:46 -03:00
|
|
|
else
|
2010-05-30 10:18:10 -03:00
|
|
|
res = Py_False;
|
2010-05-09 11:46:46 -03:00
|
|
|
|
|
|
|
Py_INCREF(res);
|
|
|
|
return res;
|
2010-05-30 10:18:10 -03:00
|
|
|
|
|
|
|
Unimplemented:
|
|
|
|
Py_INCREF(Py_NotImplemented);
|
|
|
|
return Py_NotImplemented;
|
2001-01-17 21:12:39 -04:00
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
PyErr_SetString(PyExc_TypeError,
|
|
|
|
"can't convert complex to int");
|
|
|
|
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
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
PyErr_SetString(PyExc_TypeError,
|
|
|
|
"can't convert complex to long");
|
|
|
|
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
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
PyErr_SetString(PyExc_TypeError,
|
|
|
|
"can't convert complex to float");
|
|
|
|
return NULL;
|
1996-01-11 20:47:05 -04:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2001-08-16 10:15:00 -03:00
|
|
|
complex_conjugate(PyObject *self)
|
1996-01-11 20:47:05 -04:00
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex c;
|
|
|
|
c = ((PyComplexObject *)self)->cval;
|
|
|
|
c.imag = -c.imag;
|
|
|
|
return PyComplex_FromCComplex(c);
|
1996-01-11 20:47:05 -04:00
|
|
|
}
|
|
|
|
|
Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
the complex_pow part), r56649, r56652, r56715, r57296, r57302, r57359, r57361,
r57372, r57738, r57739, r58017, r58039, r58040, and r59390, and new
documentation. The only significant difference is that round(x) returns a float
to preserve backward-compatibility. See http://bugs.python.org/issue1689.
2008-01-02 22:21:52 -04:00
|
|
|
PyDoc_STRVAR(complex_conjugate_doc,
|
|
|
|
"complex.conjugate() -> complex\n"
|
|
|
|
"\n"
|
2013-10-05 18:39:18 -03:00
|
|
|
"Return the complex conjugate of its argument. (3-4j).conjugate() == 3+4j.");
|
Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
the complex_pow part), r56649, r56652, r56715, r57296, r57302, r57359, r57361,
r57372, r57738, r57739, r58017, r58039, r58040, and r59390, and new
documentation. The only significant difference is that round(x) returns a float
to preserve backward-compatibility. See http://bugs.python.org/issue1689.
2008-01-02 22:21:52 -04:00
|
|
|
|
2003-01-29 13:58:45 -04:00
|
|
|
static PyObject *
|
|
|
|
complex_getnewargs(PyComplexObject *v)
|
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex c = v->cval;
|
|
|
|
return Py_BuildValue("(dd)", c.real, c.imag);
|
2003-01-29 13:58:45 -04:00
|
|
|
}
|
|
|
|
|
2009-04-29 21:58:58 -03:00
|
|
|
PyDoc_STRVAR(complex__format__doc,
|
|
|
|
"complex.__format__() -> str\n"
|
|
|
|
"\n"
|
2013-10-05 18:39:18 -03:00
|
|
|
"Convert to a string according to format_spec.");
|
2009-04-29 21:58:58 -03:00
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
complex__format__(PyObject* self, PyObject* args)
|
|
|
|
{
|
|
|
|
PyObject *format_spec;
|
|
|
|
|
|
|
|
if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
|
2010-05-09 11:46:46 -03:00
|
|
|
return NULL;
|
2009-04-29 21:58:58 -03:00
|
|
|
if (PyBytes_Check(format_spec))
|
2010-05-09 11:46:46 -03:00
|
|
|
return _PyComplex_FormatAdvanced(self,
|
|
|
|
PyBytes_AS_STRING(format_spec),
|
|
|
|
PyBytes_GET_SIZE(format_spec));
|
2009-04-29 21:58:58 -03:00
|
|
|
if (PyUnicode_Check(format_spec)) {
|
2010-05-09 11:46:46 -03:00
|
|
|
/* Convert format_spec to a str */
|
|
|
|
PyObject *result;
|
|
|
|
PyObject *str_spec = PyObject_Str(format_spec);
|
2009-04-29 21:58:58 -03:00
|
|
|
|
2010-05-09 11:46:46 -03:00
|
|
|
if (str_spec == NULL)
|
|
|
|
return NULL;
|
2009-04-29 21:58:58 -03:00
|
|
|
|
2010-05-09 11:46:46 -03:00
|
|
|
result = _PyComplex_FormatAdvanced(self,
|
|
|
|
PyBytes_AS_STRING(str_spec),
|
|
|
|
PyBytes_GET_SIZE(str_spec));
|
2009-04-29 21:58:58 -03:00
|
|
|
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_DECREF(str_spec);
|
|
|
|
return result;
|
2009-04-29 21:58:58 -03:00
|
|
|
}
|
|
|
|
PyErr_SetString(PyExc_TypeError, "__format__ requires str or unicode");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2008-04-18 20:13:07 -03:00
|
|
|
#if 0
|
|
|
|
static PyObject *
|
|
|
|
complex_is_finite(PyObject *self)
|
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_complex c;
|
|
|
|
c = ((PyComplexObject *)self)->cval;
|
|
|
|
return PyBool_FromLong((long)(Py_IS_FINITE(c.real) &&
|
|
|
|
Py_IS_FINITE(c.imag)));
|
2008-04-18 20:13:07 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
PyDoc_STRVAR(complex_is_finite_doc,
|
|
|
|
"complex.is_finite() -> bool\n"
|
|
|
|
"\n"
|
|
|
|
"Returns True if the real and the imaginary part is finite.");
|
|
|
|
#endif
|
|
|
|
|
1996-01-11 20:47:05 -04:00
|
|
|
static PyMethodDef complex_methods[] = {
|
2010-05-09 11:46:46 -03:00
|
|
|
{"conjugate", (PyCFunction)complex_conjugate, METH_NOARGS,
|
|
|
|
complex_conjugate_doc},
|
2008-04-18 20:13:07 -03:00
|
|
|
#if 0
|
2010-05-09 11:46:46 -03:00
|
|
|
{"is_finite", (PyCFunction)complex_is_finite, METH_NOARGS,
|
|
|
|
complex_is_finite_doc},
|
2008-04-18 20:13:07 -03:00
|
|
|
#endif
|
2010-05-09 11:46:46 -03:00
|
|
|
{"__getnewargs__", (PyCFunction)complex_getnewargs, METH_NOARGS},
|
|
|
|
{"__format__", (PyCFunction)complex__format__,
|
|
|
|
METH_VARARGS, complex__format__doc},
|
|
|
|
{NULL, NULL} /* sentinel */
|
1996-01-11 20:47:05 -04:00
|
|
|
};
|
|
|
|
|
2001-09-20 17:46:19 -03:00
|
|
|
static PyMemberDef complex_members[] = {
|
2010-05-09 11:46:46 -03:00
|
|
|
{"real", T_DOUBLE, offsetof(PyComplexObject, cval.real), READONLY,
|
|
|
|
"the real part of a complex number"},
|
|
|
|
{"imag", T_DOUBLE, offsetof(PyComplexObject, cval.imag), READONLY,
|
|
|
|
"the imaginary part of a complex number"},
|
|
|
|
{0},
|
2001-08-02 01:15:00 -03:00
|
|
|
};
|
1996-01-11 20:47:05 -04:00
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2001-08-02 01:15:00 -03:00
|
|
|
complex_subtype_from_string(PyTypeObject *type, PyObject *v)
|
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
const char *s, *start;
|
|
|
|
char *end;
|
|
|
|
double x=0.0, y=0.0, z;
|
|
|
|
int got_bracket=0;
|
2001-10-25 15:07:22 -03:00
|
|
|
#ifdef Py_USING_UNICODE
|
2010-05-09 11:46:46 -03:00
|
|
|
char *s_buffer = NULL;
|
2001-10-25 15:07:22 -03:00
|
|
|
#endif
|
2010-05-09 11:46:46 -03:00
|
|
|
Py_ssize_t len;
|
2001-08-02 01:15:00 -03:00
|
|
|
|
2010-05-09 11:46:46 -03:00
|
|
|
if (PyString_Check(v)) {
|
|
|
|
s = PyString_AS_STRING(v);
|
|
|
|
len = PyString_GET_SIZE(v);
|
|
|
|
}
|
2001-08-17 15:39:25 -03:00
|
|
|
#ifdef Py_USING_UNICODE
|
2010-05-09 11:46:46 -03:00
|
|
|
else if (PyUnicode_Check(v)) {
|
|
|
|
s_buffer = (char *)PyMem_MALLOC(PyUnicode_GET_SIZE(v)+1);
|
|
|
|
if (s_buffer == NULL)
|
|
|
|
return PyErr_NoMemory();
|
|
|
|
if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
|
|
|
|
PyUnicode_GET_SIZE(v),
|
|
|
|
s_buffer,
|
|
|
|
NULL))
|
|
|
|
goto error;
|
|
|
|
s = s_buffer;
|
|
|
|
len = strlen(s);
|
|
|
|
}
|
2001-08-17 15:39:25 -03:00
|
|
|
#endif
|
2015-11-20 15:56:21 -04:00
|
|
|
else {
|
2010-05-09 11:46:46 -03:00
|
|
|
PyErr_SetString(PyExc_TypeError,
|
|
|
|
"complex() arg is not a string");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* position on first nonblank */
|
|
|
|
start = s;
|
|
|
|
while (Py_ISSPACE(*s))
|
|
|
|
s++;
|
|
|
|
if (*s == '(') {
|
|
|
|
/* Skip over possible bracket from repr(). */
|
|
|
|
got_bracket = 1;
|
|
|
|
s++;
|
|
|
|
while (Py_ISSPACE(*s))
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* a valid complex string usually takes one of the three forms:
|
|
|
|
|
|
|
|
<float> - real part only
|
|
|
|
<float>j - imaginary part only
|
|
|
|
<float><signed-float>j - real and imaginary parts
|
|
|
|
|
|
|
|
where <float> represents any numeric string that's accepted by the
|
|
|
|
float constructor (including 'nan', 'inf', 'infinity', etc.), and
|
|
|
|
<signed-float> is any string of the form <float> whose first
|
|
|
|
character is '+' or '-'.
|
|
|
|
|
|
|
|
For backwards compatibility, the extra forms
|
|
|
|
|
|
|
|
<float><sign>j
|
|
|
|
<sign>j
|
|
|
|
j
|
|
|
|
|
|
|
|
are also accepted, though support for these forms may be removed from
|
|
|
|
a future version of Python.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* first look for forms starting with <float> */
|
|
|
|
z = PyOS_string_to_double(s, &end, NULL);
|
|
|
|
if (z == -1.0 && PyErr_Occurred()) {
|
|
|
|
if (PyErr_ExceptionMatches(PyExc_ValueError))
|
|
|
|
PyErr_Clear();
|
|
|
|
else
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (end != s) {
|
|
|
|
/* all 4 forms starting with <float> land here */
|
|
|
|
s = end;
|
|
|
|
if (*s == '+' || *s == '-') {
|
|
|
|
/* <float><signed-float>j | <float><sign>j */
|
|
|
|
x = z;
|
|
|
|
y = PyOS_string_to_double(s, &end, NULL);
|
|
|
|
if (y == -1.0 && PyErr_Occurred()) {
|
|
|
|
if (PyErr_ExceptionMatches(PyExc_ValueError))
|
|
|
|
PyErr_Clear();
|
|
|
|
else
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (end != s)
|
|
|
|
/* <float><signed-float>j */
|
|
|
|
s = end;
|
|
|
|
else {
|
|
|
|
/* <float><sign>j */
|
|
|
|
y = *s == '+' ? 1.0 : -1.0;
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
if (!(*s == 'j' || *s == 'J'))
|
|
|
|
goto parse_error;
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
else if (*s == 'j' || *s == 'J') {
|
|
|
|
/* <float>j */
|
|
|
|
s++;
|
|
|
|
y = z;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
/* <float> */
|
|
|
|
x = z;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* not starting with <float>; must be <sign>j or j */
|
|
|
|
if (*s == '+' || *s == '-') {
|
|
|
|
/* <sign>j */
|
|
|
|
y = *s == '+' ? 1.0 : -1.0;
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
/* j */
|
|
|
|
y = 1.0;
|
|
|
|
if (!(*s == 'j' || *s == 'J'))
|
|
|
|
goto parse_error;
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* trailing whitespace and closing bracket */
|
|
|
|
while (Py_ISSPACE(*s))
|
|
|
|
s++;
|
|
|
|
if (got_bracket) {
|
|
|
|
/* if there was an opening parenthesis, then the corresponding
|
|
|
|
closing parenthesis should be right here */
|
|
|
|
if (*s != ')')
|
|
|
|
goto parse_error;
|
|
|
|
s++;
|
|
|
|
while (Py_ISSPACE(*s))
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* we should now be at the end of the string */
|
|
|
|
if (s-start != len)
|
|
|
|
goto parse_error;
|
2001-08-02 01:15:00 -03:00
|
|
|
|
2009-10-26 19:28:14 -03:00
|
|
|
|
|
|
|
#ifdef Py_USING_UNICODE
|
2010-05-09 11:46:46 -03:00
|
|
|
if (s_buffer)
|
|
|
|
PyMem_FREE(s_buffer);
|
2009-10-26 19:28:14 -03:00
|
|
|
#endif
|
2010-05-09 11:46:46 -03:00
|
|
|
return complex_subtype_from_doubles(type, x, y);
|
2001-08-02 01:15:00 -03:00
|
|
|
|
2009-04-24 09:46:53 -03:00
|
|
|
parse_error:
|
2010-05-09 11:46:46 -03:00
|
|
|
PyErr_SetString(PyExc_ValueError,
|
|
|
|
"complex() arg is a malformed string");
|
2009-10-26 19:28:14 -03:00
|
|
|
error:
|
|
|
|
#ifdef Py_USING_UNICODE
|
2010-05-09 11:46:46 -03:00
|
|
|
if (s_buffer)
|
|
|
|
PyMem_FREE(s_buffer);
|
2009-10-26 19:28:14 -03:00
|
|
|
#endif
|
2010-05-09 11:46:46 -03:00
|
|
|
return NULL;
|
2001-08-02 01:15:00 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|
|
|
{
|
2010-05-09 11:46:46 -03:00
|
|
|
PyObject *r, *i, *tmp;
|
|
|
|
PyNumberMethods *nbr, *nbi = NULL;
|
|
|
|
Py_complex cr, ci;
|
|
|
|
int own_r = 0;
|
|
|
|
int cr_is_complex = 0;
|
|
|
|
int ci_is_complex = 0;
|
|
|
|
static char *kwlist[] = {"real", "imag", 0};
|
|
|
|
|
|
|
|
r = Py_False;
|
|
|
|
i = NULL;
|
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:complex", kwlist,
|
|
|
|
&r, &i))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* Special-case for a single argument when type(arg) is complex. */
|
|
|
|
if (PyComplex_CheckExact(r) && i == NULL &&
|
|
|
|
type == &PyComplex_Type) {
|
|
|
|
/* Note that we can't know whether it's safe to return
|
|
|
|
a complex *subclass* instance as-is, hence the restriction
|
|
|
|
to exact complexes here. If either the input or the
|
|
|
|
output is a complex subclass, it will be handled below
|
|
|
|
as a non-orthogonal vector. */
|
|
|
|
Py_INCREF(r);
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
if (PyString_Check(r) || PyUnicode_Check(r)) {
|
|
|
|
if (i != NULL) {
|
|
|
|
PyErr_SetString(PyExc_TypeError,
|
|
|
|
"complex() can't take second arg"
|
|
|
|
" if first is a string");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return complex_subtype_from_string(type, r);
|
|
|
|
}
|
|
|
|
if (i != NULL && (PyString_Check(i) || PyUnicode_Check(i))) {
|
|
|
|
PyErr_SetString(PyExc_TypeError,
|
|
|
|
"complex() second arg can't be a string");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp = try_complex_special_method(r);
|
|
|
|
if (tmp) {
|
|
|
|
r = tmp;
|
|
|
|
own_r = 1;
|
|
|
|
}
|
|
|
|
else if (PyErr_Occurred()) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
nbr = r->ob_type->tp_as_number;
|
|
|
|
if (i != NULL)
|
|
|
|
nbi = i->ob_type->tp_as_number;
|
|
|
|
if (nbr == NULL || nbr->nb_float == NULL ||
|
|
|
|
((i != NULL) && (nbi == NULL || nbi->nb_float == NULL))) {
|
|
|
|
PyErr_SetString(PyExc_TypeError,
|
|
|
|
"complex() argument must be a string or a number");
|
|
|
|
if (own_r) {
|
|
|
|
Py_DECREF(r);
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we get this far, then the "real" and "imag" parts should
|
|
|
|
both be treated as numbers, and the constructor should return a
|
|
|
|
complex number equal to (real + imag*1j).
|
|
|
|
|
|
|
|
Note that we do NOT assume the input to already be in canonical
|
|
|
|
form; the "real" and "imag" parts might themselves be complex
|
|
|
|
numbers, which slightly complicates the code below. */
|
|
|
|
if (PyComplex_Check(r)) {
|
|
|
|
/* Note that if r is of a complex subtype, we're only
|
|
|
|
retaining its real & imag parts here, and the return
|
|
|
|
value is (properly) of the builtin complex type. */
|
|
|
|
cr = ((PyComplexObject*)r)->cval;
|
|
|
|
cr_is_complex = 1;
|
|
|
|
if (own_r) {
|
|
|
|
Py_DECREF(r);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* The "real" part really is entirely real, and contributes
|
|
|
|
nothing in the imaginary direction.
|
|
|
|
Just treat it as a double. */
|
|
|
|
tmp = PyNumber_Float(r);
|
|
|
|
if (own_r) {
|
|
|
|
/* r was a newly created complex number, rather
|
|
|
|
than the original "real" argument. */
|
|
|
|
Py_DECREF(r);
|
|
|
|
}
|
|
|
|
if (tmp == NULL)
|
|
|
|
return NULL;
|
|
|
|
if (!PyFloat_Check(tmp)) {
|
|
|
|
PyErr_SetString(PyExc_TypeError,
|
|
|
|
"float(r) didn't return a float");
|
|
|
|
Py_DECREF(tmp);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
cr.real = PyFloat_AsDouble(tmp);
|
|
|
|
cr.imag = 0.0; /* Shut up compiler warning */
|
|
|
|
Py_DECREF(tmp);
|
|
|
|
}
|
|
|
|
if (i == NULL) {
|
|
|
|
ci.real = 0.0;
|
|
|
|
}
|
|
|
|
else if (PyComplex_Check(i)) {
|
|
|
|
ci = ((PyComplexObject*)i)->cval;
|
|
|
|
ci_is_complex = 1;
|
|
|
|
} else {
|
|
|
|
/* The "imag" part really is entirely imaginary, and
|
|
|
|
contributes nothing in the real direction.
|
|
|
|
Just treat it as a double. */
|
|
|
|
tmp = (*nbi->nb_float)(i);
|
|
|
|
if (tmp == NULL)
|
|
|
|
return NULL;
|
|
|
|
ci.real = PyFloat_AsDouble(tmp);
|
|
|
|
Py_DECREF(tmp);
|
|
|
|
}
|
|
|
|
/* If the input was in canonical form, then the "real" and "imag"
|
|
|
|
parts are real numbers, so that ci.imag and cr.imag are zero.
|
|
|
|
We need this correction in case they were not real numbers. */
|
|
|
|
|
|
|
|
if (ci_is_complex) {
|
|
|
|
cr.real -= ci.imag;
|
|
|
|
}
|
|
|
|
if (cr_is_complex) {
|
|
|
|
ci.real += cr.imag;
|
|
|
|
}
|
|
|
|
return complex_subtype_from_doubles(type, cr.real, ci.real);
|
1996-01-11 20:47:05 -04:00
|
|
|
}
|
|
|
|
|
2002-06-13 17:33:02 -03:00
|
|
|
PyDoc_STRVAR(complex_doc,
|
2001-09-12 16:12:49 -03:00
|
|
|
"complex(real[, imag]) -> complex number\n"
|
|
|
|
"\n"
|
|
|
|
"Create a complex number from a real part and an optional imaginary part.\n"
|
2002-06-13 17:33:02 -03:00
|
|
|
"This is equivalent to (real + imag*1j) where imag defaults to 0.");
|
2001-08-02 01:15:00 -03:00
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyNumberMethods complex_as_number = {
|
2010-05-09 11:46:46 -03:00
|
|
|
(binaryfunc)complex_add, /* nb_add */
|
|
|
|
(binaryfunc)complex_sub, /* nb_subtract */
|
|
|
|
(binaryfunc)complex_mul, /* nb_multiply */
|
|
|
|
(binaryfunc)complex_classic_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 */
|
|
|
|
complex_coerce, /* nb_coerce */
|
|
|
|
complex_int, /* nb_int */
|
|
|
|
complex_long, /* nb_long */
|
|
|
|
complex_float, /* nb_float */
|
|
|
|
0, /* nb_oct */
|
|
|
|
0, /* nb_hex */
|
|
|
|
0, /* nb_inplace_add */
|
|
|
|
0, /* nb_inplace_subtract */
|
|
|
|
0, /* nb_inplace_multiply*/
|
|
|
|
0, /* nb_inplace_divide */
|
|
|
|
0, /* nb_inplace_remainder */
|
|
|
|
0, /* nb_inplace_power */
|
|
|
|
0, /* nb_inplace_lshift */
|
|
|
|
0, /* nb_inplace_rshift */
|
|
|
|
0, /* nb_inplace_and */
|
|
|
|
0, /* nb_inplace_xor */
|
|
|
|
0, /* nb_inplace_or */
|
|
|
|
(binaryfunc)complex_int_div, /* nb_floor_divide */
|
|
|
|
(binaryfunc)complex_div, /* nb_true_divide */
|
|
|
|
0, /* nb_inplace_floor_divide */
|
|
|
|
0, /* nb_inplace_true_divide */
|
1996-01-11 20:47:05 -04:00
|
|
|
};
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
PyTypeObject PyComplex_Type = {
|
2010-05-09 11:46:46 -03:00
|
|
|
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
|
|
|
"complex",
|
|
|
|
sizeof(PyComplexObject),
|
|
|
|
0,
|
|
|
|
complex_dealloc, /* tp_dealloc */
|
|
|
|
(printfunc)complex_print, /* tp_print */
|
|
|
|
0, /* 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 */
|
|
|
|
PyObject_GenericGetAttr, /* tp_getattro */
|
|
|
|
0, /* tp_setattro */
|
|
|
|
0, /* tp_as_buffer */
|
|
|
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
|
|
|
|
Py_TPFLAGS_BASETYPE, /* tp_flags */
|
|
|
|
complex_doc, /* tp_doc */
|
|
|
|
0, /* tp_traverse */
|
|
|
|
0, /* tp_clear */
|
|
|
|
complex_richcompare, /* tp_richcompare */
|
|
|
|
0, /* tp_weaklistoffset */
|
|
|
|
0, /* tp_iter */
|
|
|
|
0, /* tp_iternext */
|
|
|
|
complex_methods, /* tp_methods */
|
|
|
|
complex_members, /* tp_members */
|
|
|
|
0, /* tp_getset */
|
|
|
|
0, /* tp_base */
|
|
|
|
0, /* tp_dict */
|
|
|
|
0, /* tp_descr_get */
|
|
|
|
0, /* tp_descr_set */
|
|
|
|
0, /* tp_dictoffset */
|
|
|
|
0, /* tp_init */
|
|
|
|
PyType_GenericAlloc, /* tp_alloc */
|
|
|
|
complex_new, /* tp_new */
|
|
|
|
PyObject_Del, /* tp_free */
|
1996-01-11 20:47:05 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|