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

Apakah prinsip pelaksanaan nombor kompleks dalam mesin maya Python?

王林
Lepaskan: 2023-05-13 10:40:21
ke hadapan
1408 orang telah melayarinya

    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;
    Salin selepas log masuk

    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;
    }
    Salin selepas log masuk

    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;
    }
    Salin selepas log masuk

    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)
    Salin selepas log masuk

    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;
    }
    Salin selepas log masuk

    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!

    Label berkaitan:
    sumber:yisu.com
    Kenyataan Laman Web ini
    Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
    Tutorial Popular
    Lagi>
    Muat turun terkini
    Lagi>
    kesan web
    Kod sumber laman web
    Bahan laman web
    Templat hujung hadapan