Python虚拟机中复数的实现原理是什么

发布时间:2023-03-14 11:30:43 作者:iii
来源:亿速云 阅读:93

本篇内容主要讲解“Python虚拟机中复数的实现原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python虚拟机中复数的实现原理是什么”吧!

复数数据结构

在 cpython 当中对于复数的数据结构实现如下所示:

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;

上面的数据结构图示如下:

Python虚拟机中复数的实现原理是什么

复数的数据在整个 cpython 虚拟机当中来说应该算是比较简单的了,除了一个 PyObject 头部之外就是实部和虚部了。

复数的操作

复数加法

下面是 cpython 当中对于复数加法的实现,为了简洁删除了部分无用代码。

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

上面代码的整体过程比较简单:

复数取反

复数取反操作就是将实部和虚部取相反数就可以了,这个操作也比较简单。

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

Repr 函数

我们现在来介绍一下一个有趣的方法,就是复数类型的 repr 函数,这个和类的 __repr__ 函数是作用是一样的我们看一下复数的输出是什么:

>>> data = complex(0, 1)
>>> data
1j
>>> data = complex(1, 1)
>>> data
(1+1j)
>>> print(data)
(1+1j)

复数的 repr 对应的 C 函数如下所示:

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

我们现在修改源程序将上面的 () 两个括号变成 [],编译之后执行的结果如下所示:

Python虚拟机中复数的实现原理是什么

可以看到括号变成了 [] 。

到此,相信大家对“Python虚拟机中复数的实现原理是什么”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

推荐阅读:
  1. Python中如何使用第三方netifaces库获取本机IP地址
  2. Python中如何使用自带socket库获取本机IP地址

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

python

上一篇:Oracle数据库如何完整卸载

下一篇:React父子组件间的通信是如何进行的

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》