小白學python第1問: int 占幾個字節?


windows 64位機器,python3.7;后面的文章中,沒有特別說明的話,都是在該環境下運行

int 占幾個字節?

C語言中(GCC編譯器),int 占據4個字節,python呢?
我們用python內置的 sys.getsizeof 方法來看看

28個字節! 也就是說 int 是占據 28個字節嗎? 再看看下面的

又多了4個字節!
事實上,上面的 1073741824 = 2**30,我們可以試試

sys.getsizeof(2**30-1)

這是什么原因呢,百撕不得騎姐啊;stackoverflow的這篇文章給出了答案。

https://stackoverflow.com/questions/449560/how-do-i-determine-the-size-of-an-object-in-python

我們直接看 Aaron Hall 給出的答案:

也就是說 int 類型,每2 ** 30增加4個字節。

我們試試

sys.getsizeof(2**60)

沒問題,是這個理兒

那python是怎么做到讓 int 占據的字節大小可變長而不報錯的呢?

具體地,我們看一下python的相關源碼(我的是python3.7.4)

源文件:Include/longintrepr.h

/* Long integer representation.
   The absolute value of a number is equal to
        SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i)
   Negative numbers are represented with ob_size < 0;
   zero is represented by ob_size == 0.
   In a normalized number, ob_digit[abs(ob_size)-1] (the most significant
   digit) is never zero.  Also, in all cases, for all valid i,
        0 <= ob_digit[i] <= MASK.
   The allocation function takes care of allocating extra memory
   so that ob_digit[0] ... ob_digit[abs(ob_size)-1] are actually available.

   CAUTION:  Generic code manipulating subtypes of PyVarObject has to
   aware that ints abuse  ob_size's sign bit.
*/

struct _longobject {
    PyObject_VAR_HEAD
    digit ob_digit[1];
};

PyObject_VAR_HEAD 是所有python對象共有的頭部,這里不分析,需要說明的是 這個頭部對象里面有個 ob_size 指明了可變部分的長度。
重點就是 digit ob_digit[1]
digit 是32位無符號整型(和編譯環境有關),ob_digit是一個動態數組,他存儲了int對象的真實值。真實值為數組的每一個元素 * 2**(SHIFT*i)再相加。這里的SHIFT = 30(64位系統),i 為元素在數組中的索引值。

也因為這個設計,python3.7沒有long類型只有int類型,int實際上就是值無限大(不能超出虛擬內存大小)的long。具體為什么要把int和long合並到一起,這是我們下一問了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM