繁体   English   中英

如何在 python 中准确模拟 `int32`,带符号的 2 的补码 32 位整数

[英]How to accurately emulate `int32`, signed 2's complement 32-bit integers, in python

Python 支持任意位长度的整数,但我想模拟int32 ,32 位整数,在它们所有的溢出荣耀中。

我对此没有什么问题和意见

  1. int32具有INT32_MIN = -(1 << 31)INT32_MAX = (1 << 31) - 1
  2. python 是否使用 2 的补码?
  3. int32中,正int32的第 31 位前导零,负int32的第 31 位前导零(这是因为它们是 2 的补码)。
  4. 在 python 中,正 integer 被认为有无限(或任意)多个前导,而负 integer 被认为具有无限(或任意)多个前导。

例如:

123看起来像:

  • 0b0000_0000_0000_0000_0000_0000_0111_1011 in int32
  • 0b...0_0111_1011 in python( ...0表示无限多个前导0

-123看起来像:

  • 0b1111_1111_1111_1111_1111_1111_1000_0101 in int32
  • 0b...1_1000_0101 in python( ...1表示无限多个前导1

鉴于这一切,我想出了这段代码来模拟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

当您将INT32_MAX1或从INT32_MIN减去1时,它似乎确实会溢出,这让我有信心它是正确的,但这只是两个测试用例。 这对你来说正确吗?

它看起来是正确的,您对二进制补码整数和 Python 对它们的理解也是正确的。 实现可以简化,对于简化的一些定义(也许更难掌握)。

或者它可以这样做:

def int32(x):
    x = x & 0xffffffff
    return (x ^ 0x80000000) - 0x80000000

第一行很明显,第二行通过用 XOR 翻转符号然后用减法翻转它来执行符号扩展,如果需要,这也会设置无限前导位。

  • 如果符号为零,则 XOR 设置它,减法重置它,没有任何有趣的事情发生。
  • 如果符号是 1,则 XOR 将其重置,减法将其设置但也会生成借位,因此将设置下一位,依此类推。 值得庆幸的是,这不需要无限的时间,无限的前导位是隐式的,实际上并不是一一计算的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM