⼩⽩学python第1问:int占⼏个字节?
windows 64位机器,python3.7;后⾯的⽂章中,没有特别说明的话,都是在该环境下运⾏
int 占⼏个字节?
C语⾔中(GCC编译器),int 占据4个字节,python呢?
我们⽤python内置的 sizeof ⽅法来看看
28个字节!也就是说 int 是占据 28个字节吗?再看看下⾯的
学python需要什么
⼜多了4个字节!
事实上,上⾯的 1073741824 = 2**30,我们可以试试
这是什么原因呢,百撕不得骑啊;stackoverflow的这篇⽂章给出了答案。
我们直接看 Aaron Hall 给出的答案:
也就是说 int 类型,每2 ** 30增加4个字节。
我们试试
没问题,是这个理⼉
那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合并到⼀起,这是我们下⼀问了。