Rumah > Artikel > pembangunan bahagian belakang > Apakah prinsip pelaksanaan nombor kompleks dalam mesin maya Python?
Pelaksanaan struktur data kompleks dalam cpython adalah seperti berikut:
typedef struct { double real; double imag; } Py_complex; #define PyObject_HEAD PyObject ob_base; typedef struct { PyObject_HEAD Py_complex cval; } PyComplexObject; typedef struct _object { _PyObject_HEAD_EXTRA Py_ssize_t ob_refcnt; struct _typeobject *ob_type; } PyObject;
Rajah struktur data di atas Seperti berikut :
Data kompleks seharusnya agak mudah dalam keseluruhan mesin maya cpython Selain pengepala PyObject, terdapat bahagian nyata dan khayalan.
ob_refcnt, mewakili bilangan rujukan objek Ini sangat berguna untuk kutipan sampah Nanti kita akan menganalisis bahagian kutipan sampah mesin maya.
ob_type, menunjukkan jenis data objek ini Dalam python, kadangkala perlu menilai jenis data data, seperti isinstance, type, kedua-dua kata kunci ini akan. digunakan medan.
nyata, mewakili bahagian nyata nombor kompleks.
imag, mewakili bahagian khayalan nombor kompleks.
Berikut ialah pelaksanaan penambahan nombor kompleks dalam cpython Beberapa kod yang tidak berguna telah dipadamkan untuk memudahkan .
static PyObject * complex_add(PyObject *v, PyObject *w) { Py_complex result; Py_complex a, b; TO_COMPLEX(v, a); // TO_COMPLEX 这个宏的作用就是将一个 PyComplexObject 中的 Py_complex 对象存储到 a 当中 TO_COMPLEX(w, b); result = _Py_c_sum(a, b); // 这个函数的具体实现在下方 return PyComplex_FromCComplex(result); // 这个函数的具体实现在下方 } // 真正实现复数加法的函数 Py_complex _Py_c_sum(Py_complex a, Py_complex b) { Py_complex r; r.real = a.real + b.real; r.imag = a.imag + b.imag; return r; } PyObject * PyComplex_FromCComplex(Py_complex cval) { PyComplexObject *op; /* Inline PyObject_New */ // 申请内存空间 op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject)); if (op == NULL) return PyErr_NoMemory(); // 将这个对象的引用计数设置成 1 (void)PyObject_INIT(op, &PyComplex_Type); // 将复数结构体保存下来 op->cval = cval; return (PyObject *) op; }
Proses keseluruhan kod di atas agak mudah:
Pertama ekstrak bahagian jamak sebenar daripada PyComplexObject.
Tambahkan dua nombor kompleks yang diekstrak.
Buat objek PyComplexObject berdasarkan hasil yang diperoleh, dan kembalikan objek ini.
Operasi penyongsangan nombor kompleks hanyalah untuk menyongsangkan bahagian sebenar dan bahagian khayalan Operasi ini juga agak mudah.
static PyObject * complex_neg(PyComplexObject *v) { Py_complex neg; neg.real = -v->cval.real; neg.imag = -v->cval.imag; return PyComplex_FromCComplex(neg); } PyObject * PyComplex_FromCComplex(Py_complex cval) { PyComplexObject *op; /* Inline PyObject_New */ op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject)); if (op == NULL) return PyErr_NoMemory(); (void)PyObject_INIT(op, &PyComplex_Type); op->cval = cval; return (PyObject *) op; }
Kami kini akan memperkenalkan kaedah yang menarik, iaitu fungsi repr jenis kompleks Fungsi ini mempunyai kesan yang sama seperti fungsi __repr__ kelas lihat output nombor kompleks. Apakah itu:
>>> data = complex(0, 1) >>> data 1j >>> data = complex(1, 1) >>> data (1+1j) >>> print(data) (1+1j)
Fungsi C yang sepadan dengan repr nombor kompleks adalah seperti berikut:
static PyObject * complex_repr(PyComplexObject *v) { int precision = 0; char format_code = 'r'; PyObject *result = NULL; /* If these are non-NULL, they'll need to be freed. */ char *pre = NULL; char *im = 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 = ""; // 对应实部等于 0 虚部大于 0 的情况 if (v->cval.real == 0. && copysign(1.0, v->cval.real)==1.0) { /* Real part is +0: just output the imaginary part and do not include parens. */ 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. Include parens in the result. */ // 将实部浮点数变成字符串 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 = ")"; } result = PyUnicode_FromFormat("%s%s%sj%s", lead, re, im, tail); done: PyMem_Free(im); PyMem_Free(pre); return result; }
Kami kini mengubah suai program sumber untuk menukar dua kurungan () di atas ke dalam [], dan laksanakannya selepas penyusunan Hasilnya adalah seperti berikut:
Anda boleh melihat bahawa kurungan telah bertukar kepada [].
Atas ialah kandungan terperinci Apakah prinsip pelaksanaan nombor kompleks dalam mesin maya Python?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!