有效地将 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)
我目前正在努力处理 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)