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

时间:2012-02-01 15:47:52

标签: python types

当数字的值超出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
>>> 

3 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

来自python source(在文件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的加法和减法在python中产生更多long s,无论这些值是否适合整数。

示例:

>>> 3L + 4L
7L

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

  

对于对象x和y,首先尝试x.__add__(y)。如果不是这样的话   实施或返回NotImplemented,尝试y.__add__(x)。如果这   也没有实现或返回NotImplemented,一个TypeError   异常被提出。

i - 10,其中ilong,导致另一个long