17db96d56Sopenharmony_ci 27db96d56Sopenharmony_ci/* Complex object implementation */ 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_ci/* Borrows heavily from floatobject.c */ 57db96d56Sopenharmony_ci 67db96d56Sopenharmony_ci/* Submitted by Jim Hugunin */ 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_ci#include "Python.h" 97db96d56Sopenharmony_ci#include "pycore_call.h" // _PyObject_CallNoArgs() 107db96d56Sopenharmony_ci#include "pycore_long.h" // _PyLong_GetZero() 117db96d56Sopenharmony_ci#include "pycore_object.h" // _PyObject_Init() 127db96d56Sopenharmony_ci#include "pycore_pymath.h" // _Py_ADJUST_ERANGE2() 137db96d56Sopenharmony_ci#include "structmember.h" // PyMemberDef 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_ci 167db96d56Sopenharmony_ci/*[clinic input] 177db96d56Sopenharmony_ciclass complex "PyComplexObject *" "&PyComplex_Type" 187db96d56Sopenharmony_ci[clinic start generated code]*/ 197db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=819e057d2d10f5ec]*/ 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_ci#include "clinic/complexobject.c.h" 227db96d56Sopenharmony_ci 237db96d56Sopenharmony_ci/* elementary operations on complex numbers */ 247db96d56Sopenharmony_ci 257db96d56Sopenharmony_cistatic Py_complex c_1 = {1., 0.}; 267db96d56Sopenharmony_ci 277db96d56Sopenharmony_ciPy_complex 287db96d56Sopenharmony_ci_Py_c_sum(Py_complex a, Py_complex b) 297db96d56Sopenharmony_ci{ 307db96d56Sopenharmony_ci Py_complex r; 317db96d56Sopenharmony_ci r.real = a.real + b.real; 327db96d56Sopenharmony_ci r.imag = a.imag + b.imag; 337db96d56Sopenharmony_ci return r; 347db96d56Sopenharmony_ci} 357db96d56Sopenharmony_ci 367db96d56Sopenharmony_ciPy_complex 377db96d56Sopenharmony_ci_Py_c_diff(Py_complex a, Py_complex b) 387db96d56Sopenharmony_ci{ 397db96d56Sopenharmony_ci Py_complex r; 407db96d56Sopenharmony_ci r.real = a.real - b.real; 417db96d56Sopenharmony_ci r.imag = a.imag - b.imag; 427db96d56Sopenharmony_ci return r; 437db96d56Sopenharmony_ci} 447db96d56Sopenharmony_ci 457db96d56Sopenharmony_ciPy_complex 467db96d56Sopenharmony_ci_Py_c_neg(Py_complex a) 477db96d56Sopenharmony_ci{ 487db96d56Sopenharmony_ci Py_complex r; 497db96d56Sopenharmony_ci r.real = -a.real; 507db96d56Sopenharmony_ci r.imag = -a.imag; 517db96d56Sopenharmony_ci return r; 527db96d56Sopenharmony_ci} 537db96d56Sopenharmony_ci 547db96d56Sopenharmony_ciPy_complex 557db96d56Sopenharmony_ci_Py_c_prod(Py_complex a, Py_complex b) 567db96d56Sopenharmony_ci{ 577db96d56Sopenharmony_ci Py_complex r; 587db96d56Sopenharmony_ci r.real = a.real*b.real - a.imag*b.imag; 597db96d56Sopenharmony_ci r.imag = a.real*b.imag + a.imag*b.real; 607db96d56Sopenharmony_ci return r; 617db96d56Sopenharmony_ci} 627db96d56Sopenharmony_ci 637db96d56Sopenharmony_ci/* Avoid bad optimization on Windows ARM64 until the compiler is fixed */ 647db96d56Sopenharmony_ci#ifdef _M_ARM64 657db96d56Sopenharmony_ci#pragma optimize("", off) 667db96d56Sopenharmony_ci#endif 677db96d56Sopenharmony_ciPy_complex 687db96d56Sopenharmony_ci_Py_c_quot(Py_complex a, Py_complex b) 697db96d56Sopenharmony_ci{ 707db96d56Sopenharmony_ci /****************************************************************** 717db96d56Sopenharmony_ci This was the original algorithm. It's grossly prone to spurious 727db96d56Sopenharmony_ci overflow and underflow errors. It also merrily divides by 0 despite 737db96d56Sopenharmony_ci checking for that(!). The code still serves a doc purpose here, as 747db96d56Sopenharmony_ci the algorithm following is a simple by-cases transformation of this 757db96d56Sopenharmony_ci one: 767db96d56Sopenharmony_ci 777db96d56Sopenharmony_ci Py_complex r; 787db96d56Sopenharmony_ci double d = b.real*b.real + b.imag*b.imag; 797db96d56Sopenharmony_ci if (d == 0.) 807db96d56Sopenharmony_ci errno = EDOM; 817db96d56Sopenharmony_ci r.real = (a.real*b.real + a.imag*b.imag)/d; 827db96d56Sopenharmony_ci r.imag = (a.imag*b.real - a.real*b.imag)/d; 837db96d56Sopenharmony_ci return r; 847db96d56Sopenharmony_ci ******************************************************************/ 857db96d56Sopenharmony_ci 867db96d56Sopenharmony_ci /* This algorithm is better, and is pretty obvious: first divide the 877db96d56Sopenharmony_ci * numerators and denominator by whichever of {b.real, b.imag} has 887db96d56Sopenharmony_ci * larger magnitude. The earliest reference I found was to CACM 897db96d56Sopenharmony_ci * Algorithm 116 (Complex Division, Robert L. Smith, Stanford 907db96d56Sopenharmony_ci * University). As usual, though, we're still ignoring all IEEE 917db96d56Sopenharmony_ci * endcases. 927db96d56Sopenharmony_ci */ 937db96d56Sopenharmony_ci Py_complex r; /* the result */ 947db96d56Sopenharmony_ci const double abs_breal = b.real < 0 ? -b.real : b.real; 957db96d56Sopenharmony_ci const double abs_bimag = b.imag < 0 ? -b.imag : b.imag; 967db96d56Sopenharmony_ci 977db96d56Sopenharmony_ci if (abs_breal >= abs_bimag) { 987db96d56Sopenharmony_ci /* divide tops and bottom by b.real */ 997db96d56Sopenharmony_ci if (abs_breal == 0.0) { 1007db96d56Sopenharmony_ci errno = EDOM; 1017db96d56Sopenharmony_ci r.real = r.imag = 0.0; 1027db96d56Sopenharmony_ci } 1037db96d56Sopenharmony_ci else { 1047db96d56Sopenharmony_ci const double ratio = b.imag / b.real; 1057db96d56Sopenharmony_ci const double denom = b.real + b.imag * ratio; 1067db96d56Sopenharmony_ci r.real = (a.real + a.imag * ratio) / denom; 1077db96d56Sopenharmony_ci r.imag = (a.imag - a.real * ratio) / denom; 1087db96d56Sopenharmony_ci } 1097db96d56Sopenharmony_ci } 1107db96d56Sopenharmony_ci else if (abs_bimag >= abs_breal) { 1117db96d56Sopenharmony_ci /* divide tops and bottom by b.imag */ 1127db96d56Sopenharmony_ci const double ratio = b.real / b.imag; 1137db96d56Sopenharmony_ci const double denom = b.real * ratio + b.imag; 1147db96d56Sopenharmony_ci assert(b.imag != 0.0); 1157db96d56Sopenharmony_ci r.real = (a.real * ratio + a.imag) / denom; 1167db96d56Sopenharmony_ci r.imag = (a.imag * ratio - a.real) / denom; 1177db96d56Sopenharmony_ci } 1187db96d56Sopenharmony_ci else { 1197db96d56Sopenharmony_ci /* At least one of b.real or b.imag is a NaN */ 1207db96d56Sopenharmony_ci r.real = r.imag = Py_NAN; 1217db96d56Sopenharmony_ci } 1227db96d56Sopenharmony_ci return r; 1237db96d56Sopenharmony_ci} 1247db96d56Sopenharmony_ci#ifdef _M_ARM64 1257db96d56Sopenharmony_ci#pragma optimize("", on) 1267db96d56Sopenharmony_ci#endif 1277db96d56Sopenharmony_ci 1287db96d56Sopenharmony_ciPy_complex 1297db96d56Sopenharmony_ci_Py_c_pow(Py_complex a, Py_complex b) 1307db96d56Sopenharmony_ci{ 1317db96d56Sopenharmony_ci Py_complex r; 1327db96d56Sopenharmony_ci double vabs,len,at,phase; 1337db96d56Sopenharmony_ci if (b.real == 0. && b.imag == 0.) { 1347db96d56Sopenharmony_ci r.real = 1.; 1357db96d56Sopenharmony_ci r.imag = 0.; 1367db96d56Sopenharmony_ci } 1377db96d56Sopenharmony_ci else if (a.real == 0. && a.imag == 0.) { 1387db96d56Sopenharmony_ci if (b.imag != 0. || b.real < 0.) 1397db96d56Sopenharmony_ci errno = EDOM; 1407db96d56Sopenharmony_ci r.real = 0.; 1417db96d56Sopenharmony_ci r.imag = 0.; 1427db96d56Sopenharmony_ci } 1437db96d56Sopenharmony_ci else { 1447db96d56Sopenharmony_ci vabs = hypot(a.real,a.imag); 1457db96d56Sopenharmony_ci len = pow(vabs,b.real); 1467db96d56Sopenharmony_ci at = atan2(a.imag, a.real); 1477db96d56Sopenharmony_ci phase = at*b.real; 1487db96d56Sopenharmony_ci if (b.imag != 0.0) { 1497db96d56Sopenharmony_ci len /= exp(at*b.imag); 1507db96d56Sopenharmony_ci phase += b.imag*log(vabs); 1517db96d56Sopenharmony_ci } 1527db96d56Sopenharmony_ci r.real = len*cos(phase); 1537db96d56Sopenharmony_ci r.imag = len*sin(phase); 1547db96d56Sopenharmony_ci } 1557db96d56Sopenharmony_ci return r; 1567db96d56Sopenharmony_ci} 1577db96d56Sopenharmony_ci 1587db96d56Sopenharmony_cistatic Py_complex 1597db96d56Sopenharmony_cic_powu(Py_complex x, long n) 1607db96d56Sopenharmony_ci{ 1617db96d56Sopenharmony_ci Py_complex r, p; 1627db96d56Sopenharmony_ci long mask = 1; 1637db96d56Sopenharmony_ci r = c_1; 1647db96d56Sopenharmony_ci p = x; 1657db96d56Sopenharmony_ci while (mask > 0 && n >= mask) { 1667db96d56Sopenharmony_ci if (n & mask) 1677db96d56Sopenharmony_ci r = _Py_c_prod(r,p); 1687db96d56Sopenharmony_ci mask <<= 1; 1697db96d56Sopenharmony_ci p = _Py_c_prod(p,p); 1707db96d56Sopenharmony_ci } 1717db96d56Sopenharmony_ci return r; 1727db96d56Sopenharmony_ci} 1737db96d56Sopenharmony_ci 1747db96d56Sopenharmony_cistatic Py_complex 1757db96d56Sopenharmony_cic_powi(Py_complex x, long n) 1767db96d56Sopenharmony_ci{ 1777db96d56Sopenharmony_ci if (n > 0) 1787db96d56Sopenharmony_ci return c_powu(x,n); 1797db96d56Sopenharmony_ci else 1807db96d56Sopenharmony_ci return _Py_c_quot(c_1, c_powu(x,-n)); 1817db96d56Sopenharmony_ci 1827db96d56Sopenharmony_ci} 1837db96d56Sopenharmony_ci 1847db96d56Sopenharmony_cidouble 1857db96d56Sopenharmony_ci_Py_c_abs(Py_complex z) 1867db96d56Sopenharmony_ci{ 1877db96d56Sopenharmony_ci /* sets errno = ERANGE on overflow; otherwise errno = 0 */ 1887db96d56Sopenharmony_ci double result; 1897db96d56Sopenharmony_ci 1907db96d56Sopenharmony_ci if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) { 1917db96d56Sopenharmony_ci /* C99 rules: if either the real or the imaginary part is an 1927db96d56Sopenharmony_ci infinity, return infinity, even if the other part is a 1937db96d56Sopenharmony_ci NaN. */ 1947db96d56Sopenharmony_ci if (Py_IS_INFINITY(z.real)) { 1957db96d56Sopenharmony_ci result = fabs(z.real); 1967db96d56Sopenharmony_ci errno = 0; 1977db96d56Sopenharmony_ci return result; 1987db96d56Sopenharmony_ci } 1997db96d56Sopenharmony_ci if (Py_IS_INFINITY(z.imag)) { 2007db96d56Sopenharmony_ci result = fabs(z.imag); 2017db96d56Sopenharmony_ci errno = 0; 2027db96d56Sopenharmony_ci return result; 2037db96d56Sopenharmony_ci } 2047db96d56Sopenharmony_ci /* either the real or imaginary part is a NaN, 2057db96d56Sopenharmony_ci and neither is infinite. Result should be NaN. */ 2067db96d56Sopenharmony_ci return Py_NAN; 2077db96d56Sopenharmony_ci } 2087db96d56Sopenharmony_ci result = hypot(z.real, z.imag); 2097db96d56Sopenharmony_ci if (!Py_IS_FINITE(result)) 2107db96d56Sopenharmony_ci errno = ERANGE; 2117db96d56Sopenharmony_ci else 2127db96d56Sopenharmony_ci errno = 0; 2137db96d56Sopenharmony_ci return result; 2147db96d56Sopenharmony_ci} 2157db96d56Sopenharmony_ci 2167db96d56Sopenharmony_cistatic PyObject * 2177db96d56Sopenharmony_cicomplex_subtype_from_c_complex(PyTypeObject *type, Py_complex cval) 2187db96d56Sopenharmony_ci{ 2197db96d56Sopenharmony_ci PyObject *op; 2207db96d56Sopenharmony_ci 2217db96d56Sopenharmony_ci op = type->tp_alloc(type, 0); 2227db96d56Sopenharmony_ci if (op != NULL) 2237db96d56Sopenharmony_ci ((PyComplexObject *)op)->cval = cval; 2247db96d56Sopenharmony_ci return op; 2257db96d56Sopenharmony_ci} 2267db96d56Sopenharmony_ci 2277db96d56Sopenharmony_ciPyObject * 2287db96d56Sopenharmony_ciPyComplex_FromCComplex(Py_complex cval) 2297db96d56Sopenharmony_ci{ 2307db96d56Sopenharmony_ci /* Inline PyObject_New */ 2317db96d56Sopenharmony_ci PyComplexObject *op = PyObject_Malloc(sizeof(PyComplexObject)); 2327db96d56Sopenharmony_ci if (op == NULL) { 2337db96d56Sopenharmony_ci return PyErr_NoMemory(); 2347db96d56Sopenharmony_ci } 2357db96d56Sopenharmony_ci _PyObject_Init((PyObject*)op, &PyComplex_Type); 2367db96d56Sopenharmony_ci op->cval = cval; 2377db96d56Sopenharmony_ci return (PyObject *) op; 2387db96d56Sopenharmony_ci} 2397db96d56Sopenharmony_ci 2407db96d56Sopenharmony_cistatic PyObject * 2417db96d56Sopenharmony_cicomplex_subtype_from_doubles(PyTypeObject *type, double real, double imag) 2427db96d56Sopenharmony_ci{ 2437db96d56Sopenharmony_ci Py_complex c; 2447db96d56Sopenharmony_ci c.real = real; 2457db96d56Sopenharmony_ci c.imag = imag; 2467db96d56Sopenharmony_ci return complex_subtype_from_c_complex(type, c); 2477db96d56Sopenharmony_ci} 2487db96d56Sopenharmony_ci 2497db96d56Sopenharmony_ciPyObject * 2507db96d56Sopenharmony_ciPyComplex_FromDoubles(double real, double imag) 2517db96d56Sopenharmony_ci{ 2527db96d56Sopenharmony_ci Py_complex c; 2537db96d56Sopenharmony_ci c.real = real; 2547db96d56Sopenharmony_ci c.imag = imag; 2557db96d56Sopenharmony_ci return PyComplex_FromCComplex(c); 2567db96d56Sopenharmony_ci} 2577db96d56Sopenharmony_ci 2587db96d56Sopenharmony_cidouble 2597db96d56Sopenharmony_ciPyComplex_RealAsDouble(PyObject *op) 2607db96d56Sopenharmony_ci{ 2617db96d56Sopenharmony_ci if (PyComplex_Check(op)) { 2627db96d56Sopenharmony_ci return ((PyComplexObject *)op)->cval.real; 2637db96d56Sopenharmony_ci } 2647db96d56Sopenharmony_ci else { 2657db96d56Sopenharmony_ci return PyFloat_AsDouble(op); 2667db96d56Sopenharmony_ci } 2677db96d56Sopenharmony_ci} 2687db96d56Sopenharmony_ci 2697db96d56Sopenharmony_cidouble 2707db96d56Sopenharmony_ciPyComplex_ImagAsDouble(PyObject *op) 2717db96d56Sopenharmony_ci{ 2727db96d56Sopenharmony_ci if (PyComplex_Check(op)) { 2737db96d56Sopenharmony_ci return ((PyComplexObject *)op)->cval.imag; 2747db96d56Sopenharmony_ci } 2757db96d56Sopenharmony_ci else { 2767db96d56Sopenharmony_ci return 0.0; 2777db96d56Sopenharmony_ci } 2787db96d56Sopenharmony_ci} 2797db96d56Sopenharmony_ci 2807db96d56Sopenharmony_cistatic PyObject * 2817db96d56Sopenharmony_citry_complex_special_method(PyObject *op) 2827db96d56Sopenharmony_ci{ 2837db96d56Sopenharmony_ci PyObject *f; 2847db96d56Sopenharmony_ci 2857db96d56Sopenharmony_ci f = _PyObject_LookupSpecial(op, &_Py_ID(__complex__)); 2867db96d56Sopenharmony_ci if (f) { 2877db96d56Sopenharmony_ci PyObject *res = _PyObject_CallNoArgs(f); 2887db96d56Sopenharmony_ci Py_DECREF(f); 2897db96d56Sopenharmony_ci if (!res || PyComplex_CheckExact(res)) { 2907db96d56Sopenharmony_ci return res; 2917db96d56Sopenharmony_ci } 2927db96d56Sopenharmony_ci if (!PyComplex_Check(res)) { 2937db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 2947db96d56Sopenharmony_ci "__complex__ returned non-complex (type %.200s)", 2957db96d56Sopenharmony_ci Py_TYPE(res)->tp_name); 2967db96d56Sopenharmony_ci Py_DECREF(res); 2977db96d56Sopenharmony_ci return NULL; 2987db96d56Sopenharmony_ci } 2997db96d56Sopenharmony_ci /* Issue #29894: warn if 'res' not of exact type complex. */ 3007db96d56Sopenharmony_ci if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, 3017db96d56Sopenharmony_ci "__complex__ returned non-complex (type %.200s). " 3027db96d56Sopenharmony_ci "The ability to return an instance of a strict subclass of complex " 3037db96d56Sopenharmony_ci "is deprecated, and may be removed in a future version of Python.", 3047db96d56Sopenharmony_ci Py_TYPE(res)->tp_name)) { 3057db96d56Sopenharmony_ci Py_DECREF(res); 3067db96d56Sopenharmony_ci return NULL; 3077db96d56Sopenharmony_ci } 3087db96d56Sopenharmony_ci return res; 3097db96d56Sopenharmony_ci } 3107db96d56Sopenharmony_ci return NULL; 3117db96d56Sopenharmony_ci} 3127db96d56Sopenharmony_ci 3137db96d56Sopenharmony_ciPy_complex 3147db96d56Sopenharmony_ciPyComplex_AsCComplex(PyObject *op) 3157db96d56Sopenharmony_ci{ 3167db96d56Sopenharmony_ci Py_complex cv; 3177db96d56Sopenharmony_ci PyObject *newop = NULL; 3187db96d56Sopenharmony_ci 3197db96d56Sopenharmony_ci assert(op); 3207db96d56Sopenharmony_ci /* If op is already of type PyComplex_Type, return its value */ 3217db96d56Sopenharmony_ci if (PyComplex_Check(op)) { 3227db96d56Sopenharmony_ci return ((PyComplexObject *)op)->cval; 3237db96d56Sopenharmony_ci } 3247db96d56Sopenharmony_ci /* If not, use op's __complex__ method, if it exists */ 3257db96d56Sopenharmony_ci 3267db96d56Sopenharmony_ci /* return -1 on failure */ 3277db96d56Sopenharmony_ci cv.real = -1.; 3287db96d56Sopenharmony_ci cv.imag = 0.; 3297db96d56Sopenharmony_ci 3307db96d56Sopenharmony_ci newop = try_complex_special_method(op); 3317db96d56Sopenharmony_ci 3327db96d56Sopenharmony_ci if (newop) { 3337db96d56Sopenharmony_ci cv = ((PyComplexObject *)newop)->cval; 3347db96d56Sopenharmony_ci Py_DECREF(newop); 3357db96d56Sopenharmony_ci return cv; 3367db96d56Sopenharmony_ci } 3377db96d56Sopenharmony_ci else if (PyErr_Occurred()) { 3387db96d56Sopenharmony_ci return cv; 3397db96d56Sopenharmony_ci } 3407db96d56Sopenharmony_ci /* If neither of the above works, interpret op as a float giving the 3417db96d56Sopenharmony_ci real part of the result, and fill in the imaginary part as 0. */ 3427db96d56Sopenharmony_ci else { 3437db96d56Sopenharmony_ci /* PyFloat_AsDouble will return -1 on failure */ 3447db96d56Sopenharmony_ci cv.real = PyFloat_AsDouble(op); 3457db96d56Sopenharmony_ci return cv; 3467db96d56Sopenharmony_ci } 3477db96d56Sopenharmony_ci} 3487db96d56Sopenharmony_ci 3497db96d56Sopenharmony_cistatic PyObject * 3507db96d56Sopenharmony_cicomplex_repr(PyComplexObject *v) 3517db96d56Sopenharmony_ci{ 3527db96d56Sopenharmony_ci int precision = 0; 3537db96d56Sopenharmony_ci char format_code = 'r'; 3547db96d56Sopenharmony_ci PyObject *result = NULL; 3557db96d56Sopenharmony_ci 3567db96d56Sopenharmony_ci /* If these are non-NULL, they'll need to be freed. */ 3577db96d56Sopenharmony_ci char *pre = NULL; 3587db96d56Sopenharmony_ci char *im = NULL; 3597db96d56Sopenharmony_ci 3607db96d56Sopenharmony_ci /* These do not need to be freed. re is either an alias 3617db96d56Sopenharmony_ci for pre or a pointer to a constant. lead and tail 3627db96d56Sopenharmony_ci are pointers to constants. */ 3637db96d56Sopenharmony_ci const char *re = NULL; 3647db96d56Sopenharmony_ci const char *lead = ""; 3657db96d56Sopenharmony_ci const char *tail = ""; 3667db96d56Sopenharmony_ci 3677db96d56Sopenharmony_ci if (v->cval.real == 0. && copysign(1.0, v->cval.real)==1.0) { 3687db96d56Sopenharmony_ci /* Real part is +0: just output the imaginary part and do not 3697db96d56Sopenharmony_ci include parens. */ 3707db96d56Sopenharmony_ci re = ""; 3717db96d56Sopenharmony_ci im = PyOS_double_to_string(v->cval.imag, format_code, 3727db96d56Sopenharmony_ci precision, 0, NULL); 3737db96d56Sopenharmony_ci if (!im) { 3747db96d56Sopenharmony_ci PyErr_NoMemory(); 3757db96d56Sopenharmony_ci goto done; 3767db96d56Sopenharmony_ci } 3777db96d56Sopenharmony_ci } else { 3787db96d56Sopenharmony_ci /* Format imaginary part with sign, real part without. Include 3797db96d56Sopenharmony_ci parens in the result. */ 3807db96d56Sopenharmony_ci pre = PyOS_double_to_string(v->cval.real, format_code, 3817db96d56Sopenharmony_ci precision, 0, NULL); 3827db96d56Sopenharmony_ci if (!pre) { 3837db96d56Sopenharmony_ci PyErr_NoMemory(); 3847db96d56Sopenharmony_ci goto done; 3857db96d56Sopenharmony_ci } 3867db96d56Sopenharmony_ci re = pre; 3877db96d56Sopenharmony_ci 3887db96d56Sopenharmony_ci im = PyOS_double_to_string(v->cval.imag, format_code, 3897db96d56Sopenharmony_ci precision, Py_DTSF_SIGN, NULL); 3907db96d56Sopenharmony_ci if (!im) { 3917db96d56Sopenharmony_ci PyErr_NoMemory(); 3927db96d56Sopenharmony_ci goto done; 3937db96d56Sopenharmony_ci } 3947db96d56Sopenharmony_ci lead = "("; 3957db96d56Sopenharmony_ci tail = ")"; 3967db96d56Sopenharmony_ci } 3977db96d56Sopenharmony_ci result = PyUnicode_FromFormat("%s%s%sj%s", lead, re, im, tail); 3987db96d56Sopenharmony_ci done: 3997db96d56Sopenharmony_ci PyMem_Free(im); 4007db96d56Sopenharmony_ci PyMem_Free(pre); 4017db96d56Sopenharmony_ci 4027db96d56Sopenharmony_ci return result; 4037db96d56Sopenharmony_ci} 4047db96d56Sopenharmony_ci 4057db96d56Sopenharmony_cistatic Py_hash_t 4067db96d56Sopenharmony_cicomplex_hash(PyComplexObject *v) 4077db96d56Sopenharmony_ci{ 4087db96d56Sopenharmony_ci Py_uhash_t hashreal, hashimag, combined; 4097db96d56Sopenharmony_ci hashreal = (Py_uhash_t)_Py_HashDouble((PyObject *) v, v->cval.real); 4107db96d56Sopenharmony_ci if (hashreal == (Py_uhash_t)-1) 4117db96d56Sopenharmony_ci return -1; 4127db96d56Sopenharmony_ci hashimag = (Py_uhash_t)_Py_HashDouble((PyObject *)v, v->cval.imag); 4137db96d56Sopenharmony_ci if (hashimag == (Py_uhash_t)-1) 4147db96d56Sopenharmony_ci return -1; 4157db96d56Sopenharmony_ci /* Note: if the imaginary part is 0, hashimag is 0 now, 4167db96d56Sopenharmony_ci * so the following returns hashreal unchanged. This is 4177db96d56Sopenharmony_ci * important because numbers of different types that 4187db96d56Sopenharmony_ci * compare equal must have the same hash value, so that 4197db96d56Sopenharmony_ci * hash(x + 0*j) must equal hash(x). 4207db96d56Sopenharmony_ci */ 4217db96d56Sopenharmony_ci combined = hashreal + _PyHASH_IMAG * hashimag; 4227db96d56Sopenharmony_ci if (combined == (Py_uhash_t)-1) 4237db96d56Sopenharmony_ci combined = (Py_uhash_t)-2; 4247db96d56Sopenharmony_ci return (Py_hash_t)combined; 4257db96d56Sopenharmony_ci} 4267db96d56Sopenharmony_ci 4277db96d56Sopenharmony_ci/* This macro may return! */ 4287db96d56Sopenharmony_ci#define TO_COMPLEX(obj, c) \ 4297db96d56Sopenharmony_ci if (PyComplex_Check(obj)) \ 4307db96d56Sopenharmony_ci c = ((PyComplexObject *)(obj))->cval; \ 4317db96d56Sopenharmony_ci else if (to_complex(&(obj), &(c)) < 0) \ 4327db96d56Sopenharmony_ci return (obj) 4337db96d56Sopenharmony_ci 4347db96d56Sopenharmony_cistatic int 4357db96d56Sopenharmony_cito_complex(PyObject **pobj, Py_complex *pc) 4367db96d56Sopenharmony_ci{ 4377db96d56Sopenharmony_ci PyObject *obj = *pobj; 4387db96d56Sopenharmony_ci 4397db96d56Sopenharmony_ci pc->real = pc->imag = 0.0; 4407db96d56Sopenharmony_ci if (PyLong_Check(obj)) { 4417db96d56Sopenharmony_ci pc->real = PyLong_AsDouble(obj); 4427db96d56Sopenharmony_ci if (pc->real == -1.0 && PyErr_Occurred()) { 4437db96d56Sopenharmony_ci *pobj = NULL; 4447db96d56Sopenharmony_ci return -1; 4457db96d56Sopenharmony_ci } 4467db96d56Sopenharmony_ci return 0; 4477db96d56Sopenharmony_ci } 4487db96d56Sopenharmony_ci if (PyFloat_Check(obj)) { 4497db96d56Sopenharmony_ci pc->real = PyFloat_AsDouble(obj); 4507db96d56Sopenharmony_ci return 0; 4517db96d56Sopenharmony_ci } 4527db96d56Sopenharmony_ci Py_INCREF(Py_NotImplemented); 4537db96d56Sopenharmony_ci *pobj = Py_NotImplemented; 4547db96d56Sopenharmony_ci return -1; 4557db96d56Sopenharmony_ci} 4567db96d56Sopenharmony_ci 4577db96d56Sopenharmony_ci 4587db96d56Sopenharmony_cistatic PyObject * 4597db96d56Sopenharmony_cicomplex_add(PyObject *v, PyObject *w) 4607db96d56Sopenharmony_ci{ 4617db96d56Sopenharmony_ci Py_complex result; 4627db96d56Sopenharmony_ci Py_complex a, b; 4637db96d56Sopenharmony_ci TO_COMPLEX(v, a); 4647db96d56Sopenharmony_ci TO_COMPLEX(w, b); 4657db96d56Sopenharmony_ci result = _Py_c_sum(a, b); 4667db96d56Sopenharmony_ci return PyComplex_FromCComplex(result); 4677db96d56Sopenharmony_ci} 4687db96d56Sopenharmony_ci 4697db96d56Sopenharmony_cistatic PyObject * 4707db96d56Sopenharmony_cicomplex_sub(PyObject *v, PyObject *w) 4717db96d56Sopenharmony_ci{ 4727db96d56Sopenharmony_ci Py_complex result; 4737db96d56Sopenharmony_ci Py_complex a, b; 4747db96d56Sopenharmony_ci TO_COMPLEX(v, a); 4757db96d56Sopenharmony_ci TO_COMPLEX(w, b); 4767db96d56Sopenharmony_ci result = _Py_c_diff(a, b); 4777db96d56Sopenharmony_ci return PyComplex_FromCComplex(result); 4787db96d56Sopenharmony_ci} 4797db96d56Sopenharmony_ci 4807db96d56Sopenharmony_cistatic PyObject * 4817db96d56Sopenharmony_cicomplex_mul(PyObject *v, PyObject *w) 4827db96d56Sopenharmony_ci{ 4837db96d56Sopenharmony_ci Py_complex result; 4847db96d56Sopenharmony_ci Py_complex a, b; 4857db96d56Sopenharmony_ci TO_COMPLEX(v, a); 4867db96d56Sopenharmony_ci TO_COMPLEX(w, b); 4877db96d56Sopenharmony_ci result = _Py_c_prod(a, b); 4887db96d56Sopenharmony_ci return PyComplex_FromCComplex(result); 4897db96d56Sopenharmony_ci} 4907db96d56Sopenharmony_ci 4917db96d56Sopenharmony_cistatic PyObject * 4927db96d56Sopenharmony_cicomplex_div(PyObject *v, PyObject *w) 4937db96d56Sopenharmony_ci{ 4947db96d56Sopenharmony_ci Py_complex quot; 4957db96d56Sopenharmony_ci Py_complex a, b; 4967db96d56Sopenharmony_ci TO_COMPLEX(v, a); 4977db96d56Sopenharmony_ci TO_COMPLEX(w, b); 4987db96d56Sopenharmony_ci errno = 0; 4997db96d56Sopenharmony_ci quot = _Py_c_quot(a, b); 5007db96d56Sopenharmony_ci if (errno == EDOM) { 5017db96d56Sopenharmony_ci PyErr_SetString(PyExc_ZeroDivisionError, "complex division by zero"); 5027db96d56Sopenharmony_ci return NULL; 5037db96d56Sopenharmony_ci } 5047db96d56Sopenharmony_ci return PyComplex_FromCComplex(quot); 5057db96d56Sopenharmony_ci} 5067db96d56Sopenharmony_ci 5077db96d56Sopenharmony_cistatic PyObject * 5087db96d56Sopenharmony_cicomplex_pow(PyObject *v, PyObject *w, PyObject *z) 5097db96d56Sopenharmony_ci{ 5107db96d56Sopenharmony_ci Py_complex p; 5117db96d56Sopenharmony_ci Py_complex a, b; 5127db96d56Sopenharmony_ci TO_COMPLEX(v, a); 5137db96d56Sopenharmony_ci TO_COMPLEX(w, b); 5147db96d56Sopenharmony_ci 5157db96d56Sopenharmony_ci if (z != Py_None) { 5167db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "complex modulo"); 5177db96d56Sopenharmony_ci return NULL; 5187db96d56Sopenharmony_ci } 5197db96d56Sopenharmony_ci errno = 0; 5207db96d56Sopenharmony_ci // Check whether the exponent has a small integer value, and if so use 5217db96d56Sopenharmony_ci // a faster and more accurate algorithm. 5227db96d56Sopenharmony_ci if (b.imag == 0.0 && b.real == floor(b.real) && fabs(b.real) <= 100.0) { 5237db96d56Sopenharmony_ci p = c_powi(a, (long)b.real); 5247db96d56Sopenharmony_ci } 5257db96d56Sopenharmony_ci else { 5267db96d56Sopenharmony_ci p = _Py_c_pow(a, b); 5277db96d56Sopenharmony_ci } 5287db96d56Sopenharmony_ci 5297db96d56Sopenharmony_ci _Py_ADJUST_ERANGE2(p.real, p.imag); 5307db96d56Sopenharmony_ci if (errno == EDOM) { 5317db96d56Sopenharmony_ci PyErr_SetString(PyExc_ZeroDivisionError, 5327db96d56Sopenharmony_ci "0.0 to a negative or complex power"); 5337db96d56Sopenharmony_ci return NULL; 5347db96d56Sopenharmony_ci } 5357db96d56Sopenharmony_ci else if (errno == ERANGE) { 5367db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, 5377db96d56Sopenharmony_ci "complex exponentiation"); 5387db96d56Sopenharmony_ci return NULL; 5397db96d56Sopenharmony_ci } 5407db96d56Sopenharmony_ci return PyComplex_FromCComplex(p); 5417db96d56Sopenharmony_ci} 5427db96d56Sopenharmony_ci 5437db96d56Sopenharmony_cistatic PyObject * 5447db96d56Sopenharmony_cicomplex_neg(PyComplexObject *v) 5457db96d56Sopenharmony_ci{ 5467db96d56Sopenharmony_ci Py_complex neg; 5477db96d56Sopenharmony_ci neg.real = -v->cval.real; 5487db96d56Sopenharmony_ci neg.imag = -v->cval.imag; 5497db96d56Sopenharmony_ci return PyComplex_FromCComplex(neg); 5507db96d56Sopenharmony_ci} 5517db96d56Sopenharmony_ci 5527db96d56Sopenharmony_cistatic PyObject * 5537db96d56Sopenharmony_cicomplex_pos(PyComplexObject *v) 5547db96d56Sopenharmony_ci{ 5557db96d56Sopenharmony_ci if (PyComplex_CheckExact(v)) { 5567db96d56Sopenharmony_ci Py_INCREF(v); 5577db96d56Sopenharmony_ci return (PyObject *)v; 5587db96d56Sopenharmony_ci } 5597db96d56Sopenharmony_ci else 5607db96d56Sopenharmony_ci return PyComplex_FromCComplex(v->cval); 5617db96d56Sopenharmony_ci} 5627db96d56Sopenharmony_ci 5637db96d56Sopenharmony_cistatic PyObject * 5647db96d56Sopenharmony_cicomplex_abs(PyComplexObject *v) 5657db96d56Sopenharmony_ci{ 5667db96d56Sopenharmony_ci double result; 5677db96d56Sopenharmony_ci 5687db96d56Sopenharmony_ci result = _Py_c_abs(v->cval); 5697db96d56Sopenharmony_ci 5707db96d56Sopenharmony_ci if (errno == ERANGE) { 5717db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, 5727db96d56Sopenharmony_ci "absolute value too large"); 5737db96d56Sopenharmony_ci return NULL; 5747db96d56Sopenharmony_ci } 5757db96d56Sopenharmony_ci return PyFloat_FromDouble(result); 5767db96d56Sopenharmony_ci} 5777db96d56Sopenharmony_ci 5787db96d56Sopenharmony_cistatic int 5797db96d56Sopenharmony_cicomplex_bool(PyComplexObject *v) 5807db96d56Sopenharmony_ci{ 5817db96d56Sopenharmony_ci return v->cval.real != 0.0 || v->cval.imag != 0.0; 5827db96d56Sopenharmony_ci} 5837db96d56Sopenharmony_ci 5847db96d56Sopenharmony_cistatic PyObject * 5857db96d56Sopenharmony_cicomplex_richcompare(PyObject *v, PyObject *w, int op) 5867db96d56Sopenharmony_ci{ 5877db96d56Sopenharmony_ci PyObject *res; 5887db96d56Sopenharmony_ci Py_complex i; 5897db96d56Sopenharmony_ci int equal; 5907db96d56Sopenharmony_ci 5917db96d56Sopenharmony_ci if (op != Py_EQ && op != Py_NE) { 5927db96d56Sopenharmony_ci goto Unimplemented; 5937db96d56Sopenharmony_ci } 5947db96d56Sopenharmony_ci 5957db96d56Sopenharmony_ci assert(PyComplex_Check(v)); 5967db96d56Sopenharmony_ci TO_COMPLEX(v, i); 5977db96d56Sopenharmony_ci 5987db96d56Sopenharmony_ci if (PyLong_Check(w)) { 5997db96d56Sopenharmony_ci /* Check for 0.0 imaginary part first to avoid the rich 6007db96d56Sopenharmony_ci * comparison when possible. 6017db96d56Sopenharmony_ci */ 6027db96d56Sopenharmony_ci if (i.imag == 0.0) { 6037db96d56Sopenharmony_ci PyObject *j, *sub_res; 6047db96d56Sopenharmony_ci j = PyFloat_FromDouble(i.real); 6057db96d56Sopenharmony_ci if (j == NULL) 6067db96d56Sopenharmony_ci return NULL; 6077db96d56Sopenharmony_ci 6087db96d56Sopenharmony_ci sub_res = PyObject_RichCompare(j, w, op); 6097db96d56Sopenharmony_ci Py_DECREF(j); 6107db96d56Sopenharmony_ci return sub_res; 6117db96d56Sopenharmony_ci } 6127db96d56Sopenharmony_ci else { 6137db96d56Sopenharmony_ci equal = 0; 6147db96d56Sopenharmony_ci } 6157db96d56Sopenharmony_ci } 6167db96d56Sopenharmony_ci else if (PyFloat_Check(w)) { 6177db96d56Sopenharmony_ci equal = (i.real == PyFloat_AsDouble(w) && i.imag == 0.0); 6187db96d56Sopenharmony_ci } 6197db96d56Sopenharmony_ci else if (PyComplex_Check(w)) { 6207db96d56Sopenharmony_ci Py_complex j; 6217db96d56Sopenharmony_ci 6227db96d56Sopenharmony_ci TO_COMPLEX(w, j); 6237db96d56Sopenharmony_ci equal = (i.real == j.real && i.imag == j.imag); 6247db96d56Sopenharmony_ci } 6257db96d56Sopenharmony_ci else { 6267db96d56Sopenharmony_ci goto Unimplemented; 6277db96d56Sopenharmony_ci } 6287db96d56Sopenharmony_ci 6297db96d56Sopenharmony_ci if (equal == (op == Py_EQ)) 6307db96d56Sopenharmony_ci res = Py_True; 6317db96d56Sopenharmony_ci else 6327db96d56Sopenharmony_ci res = Py_False; 6337db96d56Sopenharmony_ci 6347db96d56Sopenharmony_ci Py_INCREF(res); 6357db96d56Sopenharmony_ci return res; 6367db96d56Sopenharmony_ci 6377db96d56Sopenharmony_ciUnimplemented: 6387db96d56Sopenharmony_ci Py_RETURN_NOTIMPLEMENTED; 6397db96d56Sopenharmony_ci} 6407db96d56Sopenharmony_ci 6417db96d56Sopenharmony_ci/*[clinic input] 6427db96d56Sopenharmony_cicomplex.conjugate 6437db96d56Sopenharmony_ci 6447db96d56Sopenharmony_ciReturn the complex conjugate of its argument. (3-4j).conjugate() == 3+4j. 6457db96d56Sopenharmony_ci[clinic start generated code]*/ 6467db96d56Sopenharmony_ci 6477db96d56Sopenharmony_cistatic PyObject * 6487db96d56Sopenharmony_cicomplex_conjugate_impl(PyComplexObject *self) 6497db96d56Sopenharmony_ci/*[clinic end generated code: output=5059ef162edfc68e input=5fea33e9747ec2c4]*/ 6507db96d56Sopenharmony_ci{ 6517db96d56Sopenharmony_ci Py_complex c = self->cval; 6527db96d56Sopenharmony_ci c.imag = -c.imag; 6537db96d56Sopenharmony_ci return PyComplex_FromCComplex(c); 6547db96d56Sopenharmony_ci} 6557db96d56Sopenharmony_ci 6567db96d56Sopenharmony_ci/*[clinic input] 6577db96d56Sopenharmony_cicomplex.__getnewargs__ 6587db96d56Sopenharmony_ci 6597db96d56Sopenharmony_ci[clinic start generated code]*/ 6607db96d56Sopenharmony_ci 6617db96d56Sopenharmony_cistatic PyObject * 6627db96d56Sopenharmony_cicomplex___getnewargs___impl(PyComplexObject *self) 6637db96d56Sopenharmony_ci/*[clinic end generated code: output=689b8206e8728934 input=539543e0a50533d7]*/ 6647db96d56Sopenharmony_ci{ 6657db96d56Sopenharmony_ci Py_complex c = self->cval; 6667db96d56Sopenharmony_ci return Py_BuildValue("(dd)", c.real, c.imag); 6677db96d56Sopenharmony_ci} 6687db96d56Sopenharmony_ci 6697db96d56Sopenharmony_ci 6707db96d56Sopenharmony_ci/*[clinic input] 6717db96d56Sopenharmony_cicomplex.__format__ 6727db96d56Sopenharmony_ci 6737db96d56Sopenharmony_ci format_spec: unicode 6747db96d56Sopenharmony_ci / 6757db96d56Sopenharmony_ci 6767db96d56Sopenharmony_ciConvert to a string according to format_spec. 6777db96d56Sopenharmony_ci[clinic start generated code]*/ 6787db96d56Sopenharmony_ci 6797db96d56Sopenharmony_cistatic PyObject * 6807db96d56Sopenharmony_cicomplex___format___impl(PyComplexObject *self, PyObject *format_spec) 6817db96d56Sopenharmony_ci/*[clinic end generated code: output=bfcb60df24cafea0 input=014ef5488acbe1d5]*/ 6827db96d56Sopenharmony_ci{ 6837db96d56Sopenharmony_ci _PyUnicodeWriter writer; 6847db96d56Sopenharmony_ci int ret; 6857db96d56Sopenharmony_ci _PyUnicodeWriter_Init(&writer); 6867db96d56Sopenharmony_ci ret = _PyComplex_FormatAdvancedWriter( 6877db96d56Sopenharmony_ci &writer, 6887db96d56Sopenharmony_ci (PyObject *)self, 6897db96d56Sopenharmony_ci format_spec, 0, PyUnicode_GET_LENGTH(format_spec)); 6907db96d56Sopenharmony_ci if (ret == -1) { 6917db96d56Sopenharmony_ci _PyUnicodeWriter_Dealloc(&writer); 6927db96d56Sopenharmony_ci return NULL; 6937db96d56Sopenharmony_ci } 6947db96d56Sopenharmony_ci return _PyUnicodeWriter_Finish(&writer); 6957db96d56Sopenharmony_ci} 6967db96d56Sopenharmony_ci 6977db96d56Sopenharmony_ci/*[clinic input] 6987db96d56Sopenharmony_cicomplex.__complex__ 6997db96d56Sopenharmony_ci 7007db96d56Sopenharmony_ciConvert this value to exact type complex. 7017db96d56Sopenharmony_ci[clinic start generated code]*/ 7027db96d56Sopenharmony_ci 7037db96d56Sopenharmony_cistatic PyObject * 7047db96d56Sopenharmony_cicomplex___complex___impl(PyComplexObject *self) 7057db96d56Sopenharmony_ci/*[clinic end generated code: output=e6b35ba3d275dc9c input=3589ada9d27db854]*/ 7067db96d56Sopenharmony_ci{ 7077db96d56Sopenharmony_ci if (PyComplex_CheckExact(self)) { 7087db96d56Sopenharmony_ci Py_INCREF(self); 7097db96d56Sopenharmony_ci return (PyObject *)self; 7107db96d56Sopenharmony_ci } 7117db96d56Sopenharmony_ci else { 7127db96d56Sopenharmony_ci return PyComplex_FromCComplex(self->cval); 7137db96d56Sopenharmony_ci } 7147db96d56Sopenharmony_ci} 7157db96d56Sopenharmony_ci 7167db96d56Sopenharmony_ci 7177db96d56Sopenharmony_cistatic PyMethodDef complex_methods[] = { 7187db96d56Sopenharmony_ci COMPLEX_CONJUGATE_METHODDEF 7197db96d56Sopenharmony_ci COMPLEX___COMPLEX___METHODDEF 7207db96d56Sopenharmony_ci COMPLEX___GETNEWARGS___METHODDEF 7217db96d56Sopenharmony_ci COMPLEX___FORMAT___METHODDEF 7227db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 7237db96d56Sopenharmony_ci}; 7247db96d56Sopenharmony_ci 7257db96d56Sopenharmony_cistatic PyMemberDef complex_members[] = { 7267db96d56Sopenharmony_ci {"real", T_DOUBLE, offsetof(PyComplexObject, cval.real), READONLY, 7277db96d56Sopenharmony_ci "the real part of a complex number"}, 7287db96d56Sopenharmony_ci {"imag", T_DOUBLE, offsetof(PyComplexObject, cval.imag), READONLY, 7297db96d56Sopenharmony_ci "the imaginary part of a complex number"}, 7307db96d56Sopenharmony_ci {0}, 7317db96d56Sopenharmony_ci}; 7327db96d56Sopenharmony_ci 7337db96d56Sopenharmony_cistatic PyObject * 7347db96d56Sopenharmony_cicomplex_from_string_inner(const char *s, Py_ssize_t len, void *type) 7357db96d56Sopenharmony_ci{ 7367db96d56Sopenharmony_ci double x=0.0, y=0.0, z; 7377db96d56Sopenharmony_ci int got_bracket=0; 7387db96d56Sopenharmony_ci const char *start; 7397db96d56Sopenharmony_ci char *end; 7407db96d56Sopenharmony_ci 7417db96d56Sopenharmony_ci /* position on first nonblank */ 7427db96d56Sopenharmony_ci start = s; 7437db96d56Sopenharmony_ci while (Py_ISSPACE(*s)) 7447db96d56Sopenharmony_ci s++; 7457db96d56Sopenharmony_ci if (*s == '(') { 7467db96d56Sopenharmony_ci /* Skip over possible bracket from repr(). */ 7477db96d56Sopenharmony_ci got_bracket = 1; 7487db96d56Sopenharmony_ci s++; 7497db96d56Sopenharmony_ci while (Py_ISSPACE(*s)) 7507db96d56Sopenharmony_ci s++; 7517db96d56Sopenharmony_ci } 7527db96d56Sopenharmony_ci 7537db96d56Sopenharmony_ci /* a valid complex string usually takes one of the three forms: 7547db96d56Sopenharmony_ci 7557db96d56Sopenharmony_ci <float> - real part only 7567db96d56Sopenharmony_ci <float>j - imaginary part only 7577db96d56Sopenharmony_ci <float><signed-float>j - real and imaginary parts 7587db96d56Sopenharmony_ci 7597db96d56Sopenharmony_ci where <float> represents any numeric string that's accepted by the 7607db96d56Sopenharmony_ci float constructor (including 'nan', 'inf', 'infinity', etc.), and 7617db96d56Sopenharmony_ci <signed-float> is any string of the form <float> whose first 7627db96d56Sopenharmony_ci character is '+' or '-'. 7637db96d56Sopenharmony_ci 7647db96d56Sopenharmony_ci For backwards compatibility, the extra forms 7657db96d56Sopenharmony_ci 7667db96d56Sopenharmony_ci <float><sign>j 7677db96d56Sopenharmony_ci <sign>j 7687db96d56Sopenharmony_ci j 7697db96d56Sopenharmony_ci 7707db96d56Sopenharmony_ci are also accepted, though support for these forms may be removed from 7717db96d56Sopenharmony_ci a future version of Python. 7727db96d56Sopenharmony_ci */ 7737db96d56Sopenharmony_ci 7747db96d56Sopenharmony_ci /* first look for forms starting with <float> */ 7757db96d56Sopenharmony_ci z = PyOS_string_to_double(s, &end, NULL); 7767db96d56Sopenharmony_ci if (z == -1.0 && PyErr_Occurred()) { 7777db96d56Sopenharmony_ci if (PyErr_ExceptionMatches(PyExc_ValueError)) 7787db96d56Sopenharmony_ci PyErr_Clear(); 7797db96d56Sopenharmony_ci else 7807db96d56Sopenharmony_ci return NULL; 7817db96d56Sopenharmony_ci } 7827db96d56Sopenharmony_ci if (end != s) { 7837db96d56Sopenharmony_ci /* all 4 forms starting with <float> land here */ 7847db96d56Sopenharmony_ci s = end; 7857db96d56Sopenharmony_ci if (*s == '+' || *s == '-') { 7867db96d56Sopenharmony_ci /* <float><signed-float>j | <float><sign>j */ 7877db96d56Sopenharmony_ci x = z; 7887db96d56Sopenharmony_ci y = PyOS_string_to_double(s, &end, NULL); 7897db96d56Sopenharmony_ci if (y == -1.0 && PyErr_Occurred()) { 7907db96d56Sopenharmony_ci if (PyErr_ExceptionMatches(PyExc_ValueError)) 7917db96d56Sopenharmony_ci PyErr_Clear(); 7927db96d56Sopenharmony_ci else 7937db96d56Sopenharmony_ci return NULL; 7947db96d56Sopenharmony_ci } 7957db96d56Sopenharmony_ci if (end != s) 7967db96d56Sopenharmony_ci /* <float><signed-float>j */ 7977db96d56Sopenharmony_ci s = end; 7987db96d56Sopenharmony_ci else { 7997db96d56Sopenharmony_ci /* <float><sign>j */ 8007db96d56Sopenharmony_ci y = *s == '+' ? 1.0 : -1.0; 8017db96d56Sopenharmony_ci s++; 8027db96d56Sopenharmony_ci } 8037db96d56Sopenharmony_ci if (!(*s == 'j' || *s == 'J')) 8047db96d56Sopenharmony_ci goto parse_error; 8057db96d56Sopenharmony_ci s++; 8067db96d56Sopenharmony_ci } 8077db96d56Sopenharmony_ci else if (*s == 'j' || *s == 'J') { 8087db96d56Sopenharmony_ci /* <float>j */ 8097db96d56Sopenharmony_ci s++; 8107db96d56Sopenharmony_ci y = z; 8117db96d56Sopenharmony_ci } 8127db96d56Sopenharmony_ci else 8137db96d56Sopenharmony_ci /* <float> */ 8147db96d56Sopenharmony_ci x = z; 8157db96d56Sopenharmony_ci } 8167db96d56Sopenharmony_ci else { 8177db96d56Sopenharmony_ci /* not starting with <float>; must be <sign>j or j */ 8187db96d56Sopenharmony_ci if (*s == '+' || *s == '-') { 8197db96d56Sopenharmony_ci /* <sign>j */ 8207db96d56Sopenharmony_ci y = *s == '+' ? 1.0 : -1.0; 8217db96d56Sopenharmony_ci s++; 8227db96d56Sopenharmony_ci } 8237db96d56Sopenharmony_ci else 8247db96d56Sopenharmony_ci /* j */ 8257db96d56Sopenharmony_ci y = 1.0; 8267db96d56Sopenharmony_ci if (!(*s == 'j' || *s == 'J')) 8277db96d56Sopenharmony_ci goto parse_error; 8287db96d56Sopenharmony_ci s++; 8297db96d56Sopenharmony_ci } 8307db96d56Sopenharmony_ci 8317db96d56Sopenharmony_ci /* trailing whitespace and closing bracket */ 8327db96d56Sopenharmony_ci while (Py_ISSPACE(*s)) 8337db96d56Sopenharmony_ci s++; 8347db96d56Sopenharmony_ci if (got_bracket) { 8357db96d56Sopenharmony_ci /* if there was an opening parenthesis, then the corresponding 8367db96d56Sopenharmony_ci closing parenthesis should be right here */ 8377db96d56Sopenharmony_ci if (*s != ')') 8387db96d56Sopenharmony_ci goto parse_error; 8397db96d56Sopenharmony_ci s++; 8407db96d56Sopenharmony_ci while (Py_ISSPACE(*s)) 8417db96d56Sopenharmony_ci s++; 8427db96d56Sopenharmony_ci } 8437db96d56Sopenharmony_ci 8447db96d56Sopenharmony_ci /* we should now be at the end of the string */ 8457db96d56Sopenharmony_ci if (s-start != len) 8467db96d56Sopenharmony_ci goto parse_error; 8477db96d56Sopenharmony_ci 8487db96d56Sopenharmony_ci return complex_subtype_from_doubles(_PyType_CAST(type), x, y); 8497db96d56Sopenharmony_ci 8507db96d56Sopenharmony_ci parse_error: 8517db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 8527db96d56Sopenharmony_ci "complex() arg is a malformed string"); 8537db96d56Sopenharmony_ci return NULL; 8547db96d56Sopenharmony_ci} 8557db96d56Sopenharmony_ci 8567db96d56Sopenharmony_cistatic PyObject * 8577db96d56Sopenharmony_cicomplex_subtype_from_string(PyTypeObject *type, PyObject *v) 8587db96d56Sopenharmony_ci{ 8597db96d56Sopenharmony_ci const char *s; 8607db96d56Sopenharmony_ci PyObject *s_buffer = NULL, *result = NULL; 8617db96d56Sopenharmony_ci Py_ssize_t len; 8627db96d56Sopenharmony_ci 8637db96d56Sopenharmony_ci if (PyUnicode_Check(v)) { 8647db96d56Sopenharmony_ci s_buffer = _PyUnicode_TransformDecimalAndSpaceToASCII(v); 8657db96d56Sopenharmony_ci if (s_buffer == NULL) { 8667db96d56Sopenharmony_ci return NULL; 8677db96d56Sopenharmony_ci } 8687db96d56Sopenharmony_ci assert(PyUnicode_IS_ASCII(s_buffer)); 8697db96d56Sopenharmony_ci /* Simply get a pointer to existing ASCII characters. */ 8707db96d56Sopenharmony_ci s = PyUnicode_AsUTF8AndSize(s_buffer, &len); 8717db96d56Sopenharmony_ci assert(s != NULL); 8727db96d56Sopenharmony_ci } 8737db96d56Sopenharmony_ci else { 8747db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 8757db96d56Sopenharmony_ci "complex() argument must be a string or a number, not '%.200s'", 8767db96d56Sopenharmony_ci Py_TYPE(v)->tp_name); 8777db96d56Sopenharmony_ci return NULL; 8787db96d56Sopenharmony_ci } 8797db96d56Sopenharmony_ci 8807db96d56Sopenharmony_ci result = _Py_string_to_number_with_underscores(s, len, "complex", v, type, 8817db96d56Sopenharmony_ci complex_from_string_inner); 8827db96d56Sopenharmony_ci Py_DECREF(s_buffer); 8837db96d56Sopenharmony_ci return result; 8847db96d56Sopenharmony_ci} 8857db96d56Sopenharmony_ci 8867db96d56Sopenharmony_ci/*[clinic input] 8877db96d56Sopenharmony_ci@classmethod 8887db96d56Sopenharmony_cicomplex.__new__ as complex_new 8897db96d56Sopenharmony_ci real as r: object(c_default="NULL") = 0 8907db96d56Sopenharmony_ci imag as i: object(c_default="NULL") = 0 8917db96d56Sopenharmony_ci 8927db96d56Sopenharmony_ciCreate a complex number from a real part and an optional imaginary part. 8937db96d56Sopenharmony_ci 8947db96d56Sopenharmony_ciThis is equivalent to (real + imag*1j) where imag defaults to 0. 8957db96d56Sopenharmony_ci[clinic start generated code]*/ 8967db96d56Sopenharmony_ci 8977db96d56Sopenharmony_cistatic PyObject * 8987db96d56Sopenharmony_cicomplex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) 8997db96d56Sopenharmony_ci/*[clinic end generated code: output=b6c7dd577b537dc1 input=f4c667f2596d4fd1]*/ 9007db96d56Sopenharmony_ci{ 9017db96d56Sopenharmony_ci PyObject *tmp; 9027db96d56Sopenharmony_ci PyNumberMethods *nbr, *nbi = NULL; 9037db96d56Sopenharmony_ci Py_complex cr, ci; 9047db96d56Sopenharmony_ci int own_r = 0; 9057db96d56Sopenharmony_ci int cr_is_complex = 0; 9067db96d56Sopenharmony_ci int ci_is_complex = 0; 9077db96d56Sopenharmony_ci 9087db96d56Sopenharmony_ci if (r == NULL) { 9097db96d56Sopenharmony_ci r = _PyLong_GetZero(); 9107db96d56Sopenharmony_ci } 9117db96d56Sopenharmony_ci 9127db96d56Sopenharmony_ci /* Special-case for a single argument when type(arg) is complex. */ 9137db96d56Sopenharmony_ci if (PyComplex_CheckExact(r) && i == NULL && 9147db96d56Sopenharmony_ci type == &PyComplex_Type) { 9157db96d56Sopenharmony_ci /* Note that we can't know whether it's safe to return 9167db96d56Sopenharmony_ci a complex *subclass* instance as-is, hence the restriction 9177db96d56Sopenharmony_ci to exact complexes here. If either the input or the 9187db96d56Sopenharmony_ci output is a complex subclass, it will be handled below 9197db96d56Sopenharmony_ci as a non-orthogonal vector. */ 9207db96d56Sopenharmony_ci Py_INCREF(r); 9217db96d56Sopenharmony_ci return r; 9227db96d56Sopenharmony_ci } 9237db96d56Sopenharmony_ci if (PyUnicode_Check(r)) { 9247db96d56Sopenharmony_ci if (i != NULL) { 9257db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 9267db96d56Sopenharmony_ci "complex() can't take second arg" 9277db96d56Sopenharmony_ci " if first is a string"); 9287db96d56Sopenharmony_ci return NULL; 9297db96d56Sopenharmony_ci } 9307db96d56Sopenharmony_ci return complex_subtype_from_string(type, r); 9317db96d56Sopenharmony_ci } 9327db96d56Sopenharmony_ci if (i != NULL && PyUnicode_Check(i)) { 9337db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 9347db96d56Sopenharmony_ci "complex() second arg can't be a string"); 9357db96d56Sopenharmony_ci return NULL; 9367db96d56Sopenharmony_ci } 9377db96d56Sopenharmony_ci 9387db96d56Sopenharmony_ci tmp = try_complex_special_method(r); 9397db96d56Sopenharmony_ci if (tmp) { 9407db96d56Sopenharmony_ci r = tmp; 9417db96d56Sopenharmony_ci own_r = 1; 9427db96d56Sopenharmony_ci } 9437db96d56Sopenharmony_ci else if (PyErr_Occurred()) { 9447db96d56Sopenharmony_ci return NULL; 9457db96d56Sopenharmony_ci } 9467db96d56Sopenharmony_ci 9477db96d56Sopenharmony_ci nbr = Py_TYPE(r)->tp_as_number; 9487db96d56Sopenharmony_ci if (nbr == NULL || 9497db96d56Sopenharmony_ci (nbr->nb_float == NULL && nbr->nb_index == NULL && !PyComplex_Check(r))) 9507db96d56Sopenharmony_ci { 9517db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 9527db96d56Sopenharmony_ci "complex() first argument must be a string or a number, " 9537db96d56Sopenharmony_ci "not '%.200s'", 9547db96d56Sopenharmony_ci Py_TYPE(r)->tp_name); 9557db96d56Sopenharmony_ci if (own_r) { 9567db96d56Sopenharmony_ci Py_DECREF(r); 9577db96d56Sopenharmony_ci } 9587db96d56Sopenharmony_ci return NULL; 9597db96d56Sopenharmony_ci } 9607db96d56Sopenharmony_ci if (i != NULL) { 9617db96d56Sopenharmony_ci nbi = Py_TYPE(i)->tp_as_number; 9627db96d56Sopenharmony_ci if (nbi == NULL || 9637db96d56Sopenharmony_ci (nbi->nb_float == NULL && nbi->nb_index == NULL && !PyComplex_Check(i))) 9647db96d56Sopenharmony_ci { 9657db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 9667db96d56Sopenharmony_ci "complex() second argument must be a number, " 9677db96d56Sopenharmony_ci "not '%.200s'", 9687db96d56Sopenharmony_ci Py_TYPE(i)->tp_name); 9697db96d56Sopenharmony_ci if (own_r) { 9707db96d56Sopenharmony_ci Py_DECREF(r); 9717db96d56Sopenharmony_ci } 9727db96d56Sopenharmony_ci return NULL; 9737db96d56Sopenharmony_ci } 9747db96d56Sopenharmony_ci } 9757db96d56Sopenharmony_ci 9767db96d56Sopenharmony_ci /* If we get this far, then the "real" and "imag" parts should 9777db96d56Sopenharmony_ci both be treated as numbers, and the constructor should return a 9787db96d56Sopenharmony_ci complex number equal to (real + imag*1j). 9797db96d56Sopenharmony_ci 9807db96d56Sopenharmony_ci Note that we do NOT assume the input to already be in canonical 9817db96d56Sopenharmony_ci form; the "real" and "imag" parts might themselves be complex 9827db96d56Sopenharmony_ci numbers, which slightly complicates the code below. */ 9837db96d56Sopenharmony_ci if (PyComplex_Check(r)) { 9847db96d56Sopenharmony_ci /* Note that if r is of a complex subtype, we're only 9857db96d56Sopenharmony_ci retaining its real & imag parts here, and the return 9867db96d56Sopenharmony_ci value is (properly) of the builtin complex type. */ 9877db96d56Sopenharmony_ci cr = ((PyComplexObject*)r)->cval; 9887db96d56Sopenharmony_ci cr_is_complex = 1; 9897db96d56Sopenharmony_ci if (own_r) { 9907db96d56Sopenharmony_ci Py_DECREF(r); 9917db96d56Sopenharmony_ci } 9927db96d56Sopenharmony_ci } 9937db96d56Sopenharmony_ci else { 9947db96d56Sopenharmony_ci /* The "real" part really is entirely real, and contributes 9957db96d56Sopenharmony_ci nothing in the imaginary direction. 9967db96d56Sopenharmony_ci Just treat it as a double. */ 9977db96d56Sopenharmony_ci tmp = PyNumber_Float(r); 9987db96d56Sopenharmony_ci if (own_r) { 9997db96d56Sopenharmony_ci /* r was a newly created complex number, rather 10007db96d56Sopenharmony_ci than the original "real" argument. */ 10017db96d56Sopenharmony_ci Py_DECREF(r); 10027db96d56Sopenharmony_ci } 10037db96d56Sopenharmony_ci if (tmp == NULL) 10047db96d56Sopenharmony_ci return NULL; 10057db96d56Sopenharmony_ci assert(PyFloat_Check(tmp)); 10067db96d56Sopenharmony_ci cr.real = PyFloat_AsDouble(tmp); 10077db96d56Sopenharmony_ci cr.imag = 0.0; 10087db96d56Sopenharmony_ci Py_DECREF(tmp); 10097db96d56Sopenharmony_ci } 10107db96d56Sopenharmony_ci if (i == NULL) { 10117db96d56Sopenharmony_ci ci.real = cr.imag; 10127db96d56Sopenharmony_ci } 10137db96d56Sopenharmony_ci else if (PyComplex_Check(i)) { 10147db96d56Sopenharmony_ci ci = ((PyComplexObject*)i)->cval; 10157db96d56Sopenharmony_ci ci_is_complex = 1; 10167db96d56Sopenharmony_ci } else { 10177db96d56Sopenharmony_ci /* The "imag" part really is entirely imaginary, and 10187db96d56Sopenharmony_ci contributes nothing in the real direction. 10197db96d56Sopenharmony_ci Just treat it as a double. */ 10207db96d56Sopenharmony_ci tmp = PyNumber_Float(i); 10217db96d56Sopenharmony_ci if (tmp == NULL) 10227db96d56Sopenharmony_ci return NULL; 10237db96d56Sopenharmony_ci ci.real = PyFloat_AsDouble(tmp); 10247db96d56Sopenharmony_ci Py_DECREF(tmp); 10257db96d56Sopenharmony_ci } 10267db96d56Sopenharmony_ci /* If the input was in canonical form, then the "real" and "imag" 10277db96d56Sopenharmony_ci parts are real numbers, so that ci.imag and cr.imag are zero. 10287db96d56Sopenharmony_ci We need this correction in case they were not real numbers. */ 10297db96d56Sopenharmony_ci 10307db96d56Sopenharmony_ci if (ci_is_complex) { 10317db96d56Sopenharmony_ci cr.real -= ci.imag; 10327db96d56Sopenharmony_ci } 10337db96d56Sopenharmony_ci if (cr_is_complex && i != NULL) { 10347db96d56Sopenharmony_ci ci.real += cr.imag; 10357db96d56Sopenharmony_ci } 10367db96d56Sopenharmony_ci return complex_subtype_from_doubles(type, cr.real, ci.real); 10377db96d56Sopenharmony_ci} 10387db96d56Sopenharmony_ci 10397db96d56Sopenharmony_cistatic PyNumberMethods complex_as_number = { 10407db96d56Sopenharmony_ci (binaryfunc)complex_add, /* nb_add */ 10417db96d56Sopenharmony_ci (binaryfunc)complex_sub, /* nb_subtract */ 10427db96d56Sopenharmony_ci (binaryfunc)complex_mul, /* nb_multiply */ 10437db96d56Sopenharmony_ci 0, /* nb_remainder */ 10447db96d56Sopenharmony_ci 0, /* nb_divmod */ 10457db96d56Sopenharmony_ci (ternaryfunc)complex_pow, /* nb_power */ 10467db96d56Sopenharmony_ci (unaryfunc)complex_neg, /* nb_negative */ 10477db96d56Sopenharmony_ci (unaryfunc)complex_pos, /* nb_positive */ 10487db96d56Sopenharmony_ci (unaryfunc)complex_abs, /* nb_absolute */ 10497db96d56Sopenharmony_ci (inquiry)complex_bool, /* nb_bool */ 10507db96d56Sopenharmony_ci 0, /* nb_invert */ 10517db96d56Sopenharmony_ci 0, /* nb_lshift */ 10527db96d56Sopenharmony_ci 0, /* nb_rshift */ 10537db96d56Sopenharmony_ci 0, /* nb_and */ 10547db96d56Sopenharmony_ci 0, /* nb_xor */ 10557db96d56Sopenharmony_ci 0, /* nb_or */ 10567db96d56Sopenharmony_ci 0, /* nb_int */ 10577db96d56Sopenharmony_ci 0, /* nb_reserved */ 10587db96d56Sopenharmony_ci 0, /* nb_float */ 10597db96d56Sopenharmony_ci 0, /* nb_inplace_add */ 10607db96d56Sopenharmony_ci 0, /* nb_inplace_subtract */ 10617db96d56Sopenharmony_ci 0, /* nb_inplace_multiply*/ 10627db96d56Sopenharmony_ci 0, /* nb_inplace_remainder */ 10637db96d56Sopenharmony_ci 0, /* nb_inplace_power */ 10647db96d56Sopenharmony_ci 0, /* nb_inplace_lshift */ 10657db96d56Sopenharmony_ci 0, /* nb_inplace_rshift */ 10667db96d56Sopenharmony_ci 0, /* nb_inplace_and */ 10677db96d56Sopenharmony_ci 0, /* nb_inplace_xor */ 10687db96d56Sopenharmony_ci 0, /* nb_inplace_or */ 10697db96d56Sopenharmony_ci 0, /* nb_floor_divide */ 10707db96d56Sopenharmony_ci (binaryfunc)complex_div, /* nb_true_divide */ 10717db96d56Sopenharmony_ci 0, /* nb_inplace_floor_divide */ 10727db96d56Sopenharmony_ci 0, /* nb_inplace_true_divide */ 10737db96d56Sopenharmony_ci}; 10747db96d56Sopenharmony_ci 10757db96d56Sopenharmony_ciPyTypeObject PyComplex_Type = { 10767db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(&PyType_Type, 0) 10777db96d56Sopenharmony_ci "complex", 10787db96d56Sopenharmony_ci sizeof(PyComplexObject), 10797db96d56Sopenharmony_ci 0, 10807db96d56Sopenharmony_ci 0, /* tp_dealloc */ 10817db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 10827db96d56Sopenharmony_ci 0, /* tp_getattr */ 10837db96d56Sopenharmony_ci 0, /* tp_setattr */ 10847db96d56Sopenharmony_ci 0, /* tp_as_async */ 10857db96d56Sopenharmony_ci (reprfunc)complex_repr, /* tp_repr */ 10867db96d56Sopenharmony_ci &complex_as_number, /* tp_as_number */ 10877db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 10887db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 10897db96d56Sopenharmony_ci (hashfunc)complex_hash, /* tp_hash */ 10907db96d56Sopenharmony_ci 0, /* tp_call */ 10917db96d56Sopenharmony_ci 0, /* tp_str */ 10927db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 10937db96d56Sopenharmony_ci 0, /* tp_setattro */ 10947db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 10957db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ 10967db96d56Sopenharmony_ci complex_new__doc__, /* tp_doc */ 10977db96d56Sopenharmony_ci 0, /* tp_traverse */ 10987db96d56Sopenharmony_ci 0, /* tp_clear */ 10997db96d56Sopenharmony_ci complex_richcompare, /* tp_richcompare */ 11007db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 11017db96d56Sopenharmony_ci 0, /* tp_iter */ 11027db96d56Sopenharmony_ci 0, /* tp_iternext */ 11037db96d56Sopenharmony_ci complex_methods, /* tp_methods */ 11047db96d56Sopenharmony_ci complex_members, /* tp_members */ 11057db96d56Sopenharmony_ci 0, /* tp_getset */ 11067db96d56Sopenharmony_ci 0, /* tp_base */ 11077db96d56Sopenharmony_ci 0, /* tp_dict */ 11087db96d56Sopenharmony_ci 0, /* tp_descr_get */ 11097db96d56Sopenharmony_ci 0, /* tp_descr_set */ 11107db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 11117db96d56Sopenharmony_ci 0, /* tp_init */ 11127db96d56Sopenharmony_ci PyType_GenericAlloc, /* tp_alloc */ 11137db96d56Sopenharmony_ci complex_new, /* tp_new */ 11147db96d56Sopenharmony_ci PyObject_Del, /* tp_free */ 11157db96d56Sopenharmony_ci}; 1116