Python中的所有内容都是一个对象。所以Python中int的大小会比平时大。
>>> sys.getsizeof(int())
24
好的,但为什么2⁶³
需要多12个字节才比2⁶³ - 1
而不只是一个呢?
>>> sys.getsizeof(2**63)
36
>>> sys.getsizeof(2**62)
24
我认为2⁶³
是一个长2⁶³-1
个整数,但为什么会有12个字节的差异?
不再直观,我尝试了其他一些事情:
>>> a = 2**63
>>> a -= 2**62
>>> sys.getsizeof(a)
36
a
仍然存储为long,即使它现在可以在int中。所以这并不奇怪。但是:
>>> a -= (2**63 - 1)
>>> a = 2**63
>>> a -= (2**63 - 1)
>>> a
1L
>>> sys.getsizeof(a)
28
新尺寸。
>>> a = 2**63
>>> a -= 2**63
>>> a
0L
>>> sys.getsizeof(a)
24
返回24个字节,但仍然很长。
我得到的最后一件事:
>>> sys.getsizeof(long())
24
问题:
在这些情况下,内存存储如何工作?
子的问题:
为什么有12个字节的间隙来添加我们的直觉告诉我们只有1位?
为什么int()
和long()
为24个字节,但long(1)
已经是28个字节且int(2⁶²)
?
注意:Python 3.X的工作方式略有不同,但并不直观。在这里,我专注于Python 2.7;我没有测试以前的版本。
答案 0 :(得分:62)
为什么它为2⁶³增加12个字节,相比之下2⁶³-1而不仅仅是1个?
在LP64系统 1 上,Python 2 int
consists of正好有三个指针大小的部分:
long int
这总共是24个字节。另一方面,Python long
consists of:
2 ** 63需要64位存储,因此它适合三个30位数字。由于每个数字的宽度为4个字节,因此整个Python long
将需要24 + 3 * 4 = 36个字节。
换句话说,差异来自于long
必须单独存储数字的大小(8个额外字节),并且差异来自于存储值的空间效率稍差(12个字节用于存储数字) 2 ** 63)。包括大小,long
中的值2 ** 63占用20个字节。将其与简单int
的任何值占用的8个字节进行比较,可以得出观察到的12字节差异。
值得注意的是,Python 3只有一个整数类型,称为int
,它是可变宽度的,并且与Python 2 long
的实现方式相同。
<小时/> 1 64位Windows的不同之处在于它保留了32位
long int
,大概是为了与使用char
,short
和long
的大量旧代码的源代码兼容作为8位,16位和32位值的“方便”别名,恰好适用于16位和32位系统。要在x86-64 Windows上获得实际的64位类型,必须使用__int64
或(在较新的编译器版本上)long long
或int64_t
。由于Python 2内部依赖于Python int
在不同位置适合C long,sys.maxint
仍然是2**31-1
,即使在64位Windows上也是如此。这个怪癖也在Python 3中修复,它没有 maxint 的概念。
答案 1 :(得分:5)
虽然我没有在文档中找到它,但这是我的解释。
当值超过可以存储在int中的值时,Python 2会隐式地将Picture 3
提升为int
。新类型(long
)的大小是long
的默认大小,即32。从现在开始,变量的大小将由其值决定,该值可以上升,下来。
long
正如您所看到的,类型在from sys import getsizeof as size
a = 1
n = 32
# going up
for i in range(10):
if not i:
print 'a = %100s%13s%4s' % (str(a), type(a), size(a))
else:
print 'a = %100s%14s%3s' % (str(a), type(a), size(a))
a <<= n
# going down
for i in range(11):
print 'a = %100s%14s%3s' % (str(a), type(a), size(a))
a >>= n
a = 1 <type 'int'> 24
a = 4294967296 <type 'long'> 32
a = 18446744073709551616 <type 'long'> 36
a = 79228162514264337593543950336 <type 'long'> 40
a = 340282366920938463463374607431768211456 <type 'long'> 44
a = 1461501637330902918203684832716283019655932542976 <type 'long'> 48
a = 6277101735386680763835789423207666416102355444464034512896 <type 'long'> 52
a = 26959946667150639794667015087019630673637144422540572481103610249216 <type 'long'> 56
a = 115792089237316195423570985008687907853269984665640564039457584007913129639936 <type 'long'> 60
a = 497323236409786642155382248146820840100456150797347717440463976893159497012533375533056 <type 'long'> 64
a = 2135987035920910082395021706169552114602704522356652769947041607822219725780640550022962086936576 <type 'long'> 68
a = 497323236409786642155382248146820840100456150797347717440463976893159497012533375533056 <type 'long'> 64
a = 115792089237316195423570985008687907853269984665640564039457584007913129639936 <type 'long'> 60
a = 26959946667150639794667015087019630673637144422540572481103610249216 <type 'long'> 56
a = 6277101735386680763835789423207666416102355444464034512896 <type 'long'> 52
a = 1461501637330902918203684832716283019655932542976 <type 'long'> 48
a = 340282366920938463463374607431768211456 <type 'long'> 44
a = 79228162514264337593543950336 <type 'long'> 40
a = 18446744073709551616 <type 'long'> 36
a = 4294967296 <type 'long'> 32
a = 1 <type 'long'> 28
开始变得太大之后保持long
,初始大小为32,但是大小随着值的变化而变化(可以更高或更低) [或者相当,显然]到32)
因此,要回答您的问题,int
的基本大小为24,int
的基本大小为28,而long
也有用于保存大值的空间(以4开头) bytes - 因此long
为32个字节,但可以根据值上下移动
至于你的子问题,为新数字创建一个唯一类型(具有唯一大小)是不可能的,因此Python有&#34;子类&#34; long
类型的long
类型,处理一系列数字,因此,一旦超过旧long
的限制,您必须使用较新的,因为它也会占用更大的数字,因此它具有几个字节。