繁体   English   中英

在Python中,整数被提升为long但反之亦然。为什么?

[英]integer gets promoted to long but not vice versa in Python. Why?

当一个数字的值超出integer范围时,python将它提升为long 但是当值回到整数范围时,为什么不将它降级为int

>>> i=2147483647
>>> type(i)
<type 'int'>
>>> i = i + 1
>>> type(i)
<type 'long'>
>>> i = i - 10
>>> type(i)
<type 'long'>
>>> i
2147483638L
>>> 

int提升为long不会丢失任何信息,并且需要存储更大的数字。

降级是没有必要的,并且没有任何真正的优势 - 除了节省4字节的内存 - 这在解释语言中并不是真正的优先事项。

作为python开发团队思考int vs long的进一步证据,在python 3 int和long中是统一的。

http://docs.python.org/release/3.0.1/whatsnew/3.0.html#integers

python源代码 (在文件Objects / longobject.c中):

static PyLongObject *
x_add(PyLongObject *a, PyLongObject *b)
{
    Py_ssize_t size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
    PyLongObject *z;
    int i;
    digit carry = 0;

    /* Ensure a is the larger of the two: */
    if (size_a < size_b) {
        { PyLongObject *temp = a; a = b; b = temp; }
        { Py_ssize_t size_temp = size_a;
          size_a = size_b;
          size_b = size_temp; }
    }
    z = _PyLong_New(size_a+1);
    if (z == NULL)
        return NULL;
    for (i = 0; i < size_b; ++i) {
        carry += a->ob_digit[i] + b->ob_digit[i];
        z->ob_digit[i] = carry & MASK;
        carry >>= SHIFT;
    }
    for (; i < size_a; ++i) {
        carry += a->ob_digit[i];
        z->ob_digit[i] = carry & MASK;
        carry >>= SHIFT;
    }
    z->ob_digit[i] = carry;
    return long_normalize(z);
}

/* Subtract the absolute values of two integers. */

static PyLongObject *
x_sub(PyLongObject *a, PyLongObject *b)
{
    Py_ssize_t size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
    PyLongObject *z;
    Py_ssize_t i;
    int sign = 1;
    digit borrow = 0;

    /* Ensure a is the larger of the two: */
    if (size_a < size_b) {
        sign = -1;
        { PyLongObject *temp = a; a = b; b = temp; }
        { Py_ssize_t size_temp = size_a;
          size_a = size_b;
          size_b = size_temp; }
    }
    else if (size_a == size_b) {
        /* Find highest digit where a and b differ: */
        i = size_a;
        while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
            ;
        if (i < 0)
            return _PyLong_New(0);
        if (a->ob_digit[i] < b->ob_digit[i]) {
            sign = -1;
            { PyLongObject *temp = a; a = b; b = temp; }
        }
        size_a = size_b = i+1;
    }
    z = _PyLong_New(size_a);
    if (z == NULL)
        return NULL;
    for (i = 0; i < size_b; ++i) {
        /* The following assumes unsigned arithmetic
           works module 2**N for some N>SHIFT. */
        borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
        z->ob_digit[i] = borrow & MASK;
        borrow >>= SHIFT;
        borrow &= 1; /* Keep only one sign bit */
    }
    for (; i < size_a; ++i) {
        borrow = a->ob_digit[i] - borrow;
        z->ob_digit[i] = borrow & MASK;
        borrow >>= SHIFT;
        borrow &= 1; /* Keep only one sign bit */
    }
    assert(borrow == 0);
    if (sign < 0)
        z->ob_size = -(z->ob_size);
    return long_normalize(z);
}

请注意,两个过程的返回类型都是PyLongObject *

这表明, long和减去long s会在python中产生更长的s,无论这些值是否适合整数。

例:

>>> 3L + 4L
7L

是python的强制规则,具体来说:

对于对象x和y,首先尝试x.__add__(y) 如果未实现或返回NotImplemented ,则尝试使用y.__add__(x) 如果这也未实现或返回NotImplemented,则引发TypeError异常。

所以做i - 10ilong ,导致另一个long

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM