Python 3 的 int 类型详解(为什么 int 不存在溢出问题?)
在以前的Python2中,整型分為int和long,也就是整型和長整型, 長整型不存在溢出問題, 即可以存放任意大小的數(shù)值,理論支持無限大數(shù)字。
因此在Python3 中,統(tǒng)一使用長整型,用int表示,在Python3中不存在long,只有int。
這個長整形int結(jié)構(gòu)其實也很簡單, 在 longintepr.h 中定義:
struct _longobject {PyObject_VAR_HEADdigit ob_digit[1]; };ob_digit它是一個數(shù)組指針。digit 可認為是 int 的別名.
即長整型在Python內(nèi)部是用一個int數(shù)組digit ob_digit[n]保存值的. 待存儲的數(shù)值的低位信息放于低位下標, 高位信息放于高下標.比如要保存 112233445566778899 很長,但我們的int只能保存6位(假設):
那么python就會這樣存儲:
低位存于低索引下,高位位于高索引下。而正負符號信息由ob_size保存, 像上面的例子中對象元素個數(shù)是3, 那么ob_size = 3而如果表示數(shù)是負數(shù)的, 那么 ob_size = -3
python中整型結(jié)構(gòu)中的數(shù)組,每個元素最大存儲 15 位的二進制數(shù)(不同位數(shù)操作系統(tǒng)有差異32位系統(tǒng)存15位,64位系統(tǒng)是30位)。
如64位系統(tǒng)最大存儲30位的二進制數(shù),即存儲的最大十進制數(shù)是 2^30-1 = 1073741823,也就是說上面例子中數(shù)組一個元素存儲的最大值是1073741823。
那么存儲數(shù)字 10737418231 其實是:
ob_digit[0] = 1; ob_digit[1] = 1073741823;需要注意的是,實際存儲是以二進制形式存儲,而非我們所寫的十進制。
-
十進制:1073741823 = 二進制:11111…11111(30位) 存儲在高索引 1
-
十進制:1 = 二進制:00000…000001(30位) 存儲在低索引 0
1 ~ 2^30-1 需要一個數(shù)組元素存放
2^30 ~ 2^60-1 需要兩個數(shù)組元素存放
以此類推……
通過代碼來看:
''' 遇到問題沒人解答?小編創(chuàng)建了一個Python學習交流QQ群:579817333 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' import sysprint("2^30 = {}\n2^60 = {}".format(1024*1024*1024, 1024*1024*1024*1024*1024*1024))print("0, 1, 2^30-1, 2^30, 2^60-1 的字節(jié)大小: ",sys.getsizeof(0), sys.getsizeof(1), sys.getsizeof(1073741823), sys.getsizeof(1073741824), sys.getsizeof(1152921504606846975))結(jié)果如下:
2^30 = 1073741824 2^60 = 1152921504606846976 數(shù)字 0, 1, 2^30-1, 2^30, 2^60-1,2^60 的字節(jié)大小: 24 28 28 32 32 36由于Python中的int有一個基礎內(nèi)存占用(也就是長整形結(jié)構(gòu)中PyObject_VAR_HEAD占用內(nèi)存的大小,24字節(jié)),因此數(shù)字1 ~ 2^30-1 內(nèi)存大小是28字節(jié),2^30 ~ 2^60-1 內(nèi)存大小是32字節(jié),這里需要注意的是 0 占用的內(nèi)存大小是24字節(jié)而非28字節(jié)!
一個數(shù)組元素的所用內(nèi)存大小是4字節(jié)即32位,但其實存儲數(shù)字的有效位是30位(64位系統(tǒng)中),少的兩位去哪了???
實際存儲只用了30位的原因是:指數(shù)運算中要求位移量得是 5 的倍數(shù),可能是某種優(yōu)化算法。
總結(jié)
以上是生活随笔為你收集整理的Python 3 的 int 类型详解(为什么 int 不存在溢出问题?)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python中的zip()函数和map(
- 下一篇: 6种Python字符串反转方式