有效地将 python 整数切割为 32 位整数

Cutting python integer to 32 bits integer efficiently

我目前正在努力处理 python 的位运算,因为 python3 32 位整数 (int) 和 64 位整数 (long) 之间没有区别。

我想要的是一个高效函数,它接受任何整数并削减最高有效的 32 位,然后将这 32 位转换回具有正确符号的整数。

示例 1:

>>> bin_string = bin(3293670138 & 0b11111111111111111111111111111111)
>>> print(bin_string)
0b11000100010100010110101011111010
>>> print(int(bin_string,2))
3293670138

但结果应该是-1001297158,因为将'11000100010100010110101011111010'转换为32位整数是负数。

我已经有了自己的解决方案:

def int32(val):
    if val >= -2**31 and val <= 2**31-1:
        return val
    bin_string = bin(val & 0b11111111111111111111111111111111)
    int_val = int(bin_string,2)
    if int_val > 2147483647:
        return -(~(int_val-1)%2**32)
    return int_val

不过,我想知道是否有人有更优雅、更高效的想法。

提前致谢!

明显更简单的解决方案:让 ctypes 为您完成工作。

from ctypes import c_int32

def int32(val):
    return c_int32(val).value

这只是从提供的 Python int 构造一个 c_int32 类型,它会根据您的需要进行截断,然后将值作为正常 Python int类型。对于实际需要修整的值,所花费的时间少于现有函数所花费的时间。在我的机器上,可靠地需要大约 155-175 ns,其中你的函数变化更大,正值大约需要 310-320 ns,负值大约需要 405-415 ns。

对于不需要修整的值来说速度较慢;您的代码以相对便宜的方式排除了它们(我通过将测试更改为 if -2 ** 31 <= val < 2 ** 31: 略微改进了它),耗时约 75 ns,但无论如何此代码都会进行转换,花费大致相同的固定时间。如果数字通常合适,并且性能很关键,您可以按照原始代码(我稍作修改)的方式进行快捷方式:

def int32(val):
    if -2 ** 31 <= val < 2 ** 31:
        return val
    return c_int32(val).value

这使得“必须截断”的情况稍微慢一些(略低于 200 纳秒),以换取使“不需要截断”的情况更快(低于 80 纳秒)。

重要的是,无论哪种方式,它都相当简单。不涉及维护复杂的代码,主要是self-documenting;你告诉它生成一个带符号的 32 位 int,它就这样做了。

使用很棒的位串库。

from bitstring import BitArray

x = BitArray(bin='11000100010100010110101011111010')
print(x.int)