CPython 源码中整数加法的实现

最近突然涌起兴趣去阅读 CPython 源码,网上也看了不少解析的文章,后来网上看到《Python源码剖析》评价不错,可惜现在已经绝版,只能从豆瓣阅读购买了一本电子书观摩 。

我从网上下载的是最新的 Python 2.7 源码,这本书配套的解说代码是 Python 2.5 的,这是一个遗憾,但是大体上相差不大,刚好昨天遇到一处。

昨天看到 Python int 实现的原理,这里不详细表述,有兴趣的可以去看看书。其中整数加法 (int_add) 的实现,虽然代码只有几行,但是其中隐藏的知识点还是非常多的,花了点时间回顾了一些基础知识,在这里也简单总结下。

以下是 2.5 里面加法的实现,也是书中提供的例子,这里直接引用过来作为参考对比,注释是作者加入的。

static PyObject* int_add(PyIntObject *v, PyIntObject *w)
{
    register long a, b, x;
    CONVERT_TO_LONG(v, a);
    CONVERT_TO_LONG(w, b);
    x = a + b;
    //[1] : 检查加法结果是否溢出
    if ((x^a) >= 0 || (x^b) >= 0)
        return PyInt_FromLong(x);
    return PyLong_Type.tp_as_number->nb_add((PyObject *)v, (PyObject *)w);
}

下面是 2.7 中的代码对比,大体都没有变化:

static PyObject *
int_add(PyIntObject *v, PyIntObject *w)
{
    register long a, b, x;
    CONVERT_TO_LONG(v, a);
    CONVERT_TO_LONG(w, b);
    /* casts in the line below avoid undefined behaviour on overflow */
    x = (long)((unsigned long)a + b);
    if ((x^a) >= 0 || (x^b) >= 0)
        return PyInt_FromLong(x);
    return PyLong_Type.tp_as_number->nb_add((PyObject *)v, (PyObject *)w);
}

继续阅读