Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Apakah prinsip pelaksanaan nombor kompleks dalam mesin maya Python?

Apakah prinsip pelaksanaan nombor kompleks dalam mesin maya Python?

王林
王林ke hadapan
2023-05-13 10:40:211372semak imbas

    Struktur data kompleks

    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 :

    Apakah prinsip pelaksanaan nombor kompleks dalam mesin maya Python?

    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.

    Operasi nombor kompleks

    Tambahan 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.

    Penyongsangan nombor kompleks

    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;
    }

    Fungsi Repr

    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:

    Apakah prinsip pelaksanaan nombor kompleks dalam mesin maya Python?

    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!

    Kenyataan:
    Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam