为什么False值(0)的字节数小于True(1)? [英] Why is a False value (0) smaller in bytes than True (1)?

查看:121
本文介绍了为什么False值(0)的字节数小于True(1)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在玩 sys getsizeof()时发现 False (或 0 )的字节数少于 True (或 1 )。为什么?

I was playing around with sys's getsizeof() and found that False (or 0) consists of less bytes than True (or 1). Why is that?

import sys

print("Zero: " + str(sys.getsizeof(0)))
print("One: " + str(sys.getsizeof(1)))
print("False: " + str(sys.getsizeof(False)))
print("True: " + str(sys.getsizeof(True)))

# Prints:
# Zero: 24
# One: 28
# False: 24
# True: 28

实际上,其他数字(也包括多于一个数字)为28个字节。

In fact, other numbers (also some that consist of more than one digit) are 28 bytes.

for n in range(0, 12):
  print(str(n) + ": " + str(sys.getsizeof(n)))

# Prints:
# 0: 24
# 1: 28
# 2: 28
# 3: 28
# 4: 28
# 5: 28
# 6: 28
# 7: 28
# 8: 28
# 9: 28
# 10: 28
# 11: 28

甚至更多: sys.getsizeof(999999999)也是28个字节! sys.getsizeof(9999999999)是32。

Even more: sys.getsizeof(999999999) is also 28 bytes! sys.getsizeof(9999999999), however, is 32.

那是怎么回事?我假设布尔值 True False 在内部转换为 0 1 ,但是为什么大小与其他较小的整数零不同?

So what's going on? I assume that the booleans True and False are internally converted to 0 and 1 respectively, but why is zero different in size from other lower integers?

侧面问题:这是特定于Python(3)表示这些项目的方式,还是通常在操作系统中显示数字的方式?

Side question: is this specific to how Python (3) represents these items, or is this generally how digits are presented in the OS?

推荐答案

请记住,Python int 值的大小是任意的。

Remember that Python int values are of arbitrary size. How does that work?

好吧,在CPython中, 1 一个int表示为 PyLong_Object ,其中包含4个字节的块 2 数组,每个块包含30位数字的值 3

Well, in CPython,1 an int is represented by a PyLong_Object, which has an array of 4-byte chunks2, each holding 30 bits3 worth of the number.


  • 0 一点也不花钱。

  • 1 -(1 << <30)-1 需要1个块。

  • 1<< 30 -(1 << 60)-1 需要2个块。

  • 0 takes no chunks at all.
  • 1 - (1<<30)-1 takes 1 chunk.
  • 1<<30 - (1<<60)-1 takes 2 chunks.

等等。

这有点过分简化了;有关完整的详细信息,请参见 longintrepr.h

This is slightly oversimplified; for full details, see longintrepr.h in the source.

在Python 2中,有两种不同的类型,称为 int long int 由直接嵌入标头(而不是块数组)的C 32位带符号整数 4 表示。 long 就像Python 3 int

In Python 2, there are two separate types, called int and long. An int is represented by a C 32-bit signed integer4 embedded directly in the header, instead of an array of chunks. A long is like a Python 3 int.

如果对 0L 1L 等进行相同的测试,则明确要求 long 值,您将获得与Python 3相同的结果。但是如果没有 L 后缀,则任何适合32位的文字都将为您提供一个 int ,只有太大的文字会给您个长 s。 5 (这表示(1 << 31)-1 int ,但 1< < 31 是2个块的 long 。)

If you do the same test with 0L, 1L, etc., to explicitly ask for long values, you will get the same results as in Python 3. But without the L suffix, any literal that fits in 32 bits gives you an int, and only literals that are too big give you longs.5 (This means that (1<<31)-1 is an int, but 1<<31 is a 2-chunk long.)

1。在不同的实现中,可能并非如此。在IIRC中,Jython的功能与CPython大致相同,但是IronPython使用C# bignum实现。

2。为什么用30位而不是32位?主要是因为 pow ** 的实现可以更简单,更快捷,如果可以假设 10 可以除以两个数字。

2. Why 30 bits instead of 32? Mainly because the implementation of pow and ** can be simpler and faster if it can assume that the number of bits in two "digits" is divisible by 10.

3。它使用C 结构黑客 。从技术上讲, Py_LongObject 是28个字节,但是没有人分配 Py_LongObject ;他们malloc 24、28、32、36等字节,然后转换为 Py_LongObject *

3. It uses the C "struct hack". Technically, a Py_LongObject is 28 bytes, but nobody ever allocates a Py_LongObject; they malloc 24, 28, 32, 36, etc. bytes then cast to Py_LongObject *.

4。实际上,Python int 是C long ,只是使事情变得混乱。因此,C API充满了 PyInt_FromLong 之类的内容,其中 long 表示 32位int,而 PyLong_FromSize_t ,其中 long 表示 bignum。

4. In fact, a Python int is a C long, just to make things confusing. So the C API is full of things like PyInt_FromLong where the long means "32-bit int" and PyLong_FromSize_t where the long means "bignum".

5。早期版本的Python 2.x并没有很好地集成 int long ,但是希望没有人担心那些。

5. Early versions of Python 2.x didn't integrate int and long as nicely, but hopefully nobody has to worry about those anymore.

这篇关于为什么False值(0)的字节数小于True(1)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆