python - 如何在python中准确模拟`int32`,有符号2的补码32位整数
问题描述
Python 支持任意位长度的整数,但我想模拟int32
32 位整数的所有溢出荣耀。
我对此有几个问题和意见
int32
有INT32_MIN = -(1 << 31)
并且INT32_MAX = (1 << 31) - 1
- python是否使用2的补码?
- 在 中
int32
,正int32
数的前导零一直到第 31 位,负数的前导零一直到第int32
31 位(这是因为它们是 2 的补码)。 - 在python中,正整数被认为具有无限(或任意)多个前导数,负整数被认为具有无限(或任意)多个前导数。
例如:
123
看起来像:
0b0000_0000_0000_0000_0000_0000_0111_1011
在int32
0b...0_0111_1011
在 python 中(...0
表示无限多个前导0
)
-123
看起来像:
0b1111_1111_1111_1111_1111_1111_1000_0101
在int32
0b...1_1000_0101
在 python 中(...1
表示无限多个前导1
)
鉴于这一切,我想出了这段代码来 emulate int32
,但想要检查一下:
INT32_MIN = -(1 << 31)
INT32_MAX = (1 << 31) - 1
INT32_MASK = (1 << 32) - 1
INT32_SIGNBIT = 1 << 31
def int32(x):
sb = bool(x & INT32_SIGNBIT)
i32 = x & INT32_MASK
if sb:
i32 += ~INT32_MASK
return i32
a = int32(INT32_MAX + 1)
b = int32(INT32_MIN - 1)
aa = a == INT32_MIN
bb = b == INT32_MAX
1
当您添加到INT32_MAX
或减去1
时,它似乎确实会溢出INT32_MIN
,所以这让我相信它是正确的,但这只是两个测试用例。这对您来说是否正确?
解决方案
它看起来是正确的,并且您对二进制补码整数和 Python 对它们的理解也是正确的。对于简化的某些定义(可能更难掌握),可以简化实现。
或者,它可以这样做:
def int32(x):
x = x & 0xffffffff
return (x ^ 0x80000000) - 0x80000000
第一行很明显,第二行通过用 XOR 翻转符号然后用减法将其翻转回来来执行符号扩展,如果需要,这也将设置无限的前导位。
- 如果符号为零,则 XOR 设置它,减法重置它,没有任何有趣的事情发生。
- 如果符号为 1,则 XOR 将其重置,减法将其设置但也会产生借位,因此将设置下一位,依此类推。值得庆幸的是,这并不需要无限的时间,无限的前导位是隐含的,实际上并未逐一计算。
推荐阅读
- r - 需要帮助编写循环函数
- java - Cannot convert row to model
- scip - 有没有办法将用户数据添加到 SCIP 中的节点?
- java - Eclipse 错误:发生错误,请参阅日志文件
- gitlab - Gitlab API 获取提交的大小
- python - 在python的饼图中摆脱不需要的绘图数据
- python - 如何在Python中的IF语句之外访问在IF语句中声明的变量
- flutter - 我有一个计算器应用程序的弹出菜单。当我选择计算器时,什么也没有发生。我究竟做错了什么?这三个计算器都是有状态的
- python - 为什么我的光线投射总是穿过墙壁?
- mongodb - java.lang.ClassNotFoundException:使用 spark-submit 时找不到数据源:com.mongodb.spark.sql.DefaultSource