2012-02-01 27 views
4

當某個數字的值超出integer範圍時,python會將其提升爲long。但是當這個值回到整數範圍時,爲什麼它不被降爲intinteger在Python中被提升爲long,反之亦然。爲什麼?

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

爲什麼要這樣呢? – Moe 2012-02-01 15:49:51

+0

我只是覺得將它降級是有意義的。 – 2012-02-01 15:53:38

+0

「有意義降級」?怎麼樣?它會失去信息。任何大於2147483647的東西都不能被「降級」而不會損失部分價值。你能解釋一下這有什麼意義嗎? – 2012-02-01 16:37:50

回答

1

python source(文件對象/ 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 *

這顯示的是,無論值是否適合ints,在python中加減long s都會產生更多long s。

實施例:

>>> 3L + 4L 
7L 

而且here是python的強制規則,具體有:

對於對象的x和y,第一x.__add__(y)試圖。如果這不是 實施或返回NotImplemented,則嘗試y.__add__(x)。如果此 也未實現或者返回NotImplemented,則會引發TypeError 異常。

這樣算下來i - 10,其中ilong,導致另一long

4

促進了intlong不會丟失任何信息和需要存儲較大的數字。

降級不是必需的,不會有任何真正的優勢 - 除了保存4字節的內存 - 這在解釋型語言中並不是真正的優先級。

+0

*不會有任何真正的優勢 - 除了保存4bytes的內存* - 謝謝指出。 – 2012-02-01 15:58:38

相關問題