简体   繁体   English

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

[英]Cutting python integer to 32 bits integer efficiently

I'm currently struggling with python's bit operations as in python3 there is no difference anymore between 32bit integers (int) and 64bit integers (long).我目前正在为 python 的位操作而苦苦挣扎,因为在 python3 中,32 位整数 (int) 和 64 位整数 (long) 之间不再有区别。

What I want is an efficient function that takes any integer and cuts the most significant 32 bits and then converts these 32 bits back to an integer with the correct sign.我想要的是一个有效的函数,它接受任何整数并削减最高有效的 32 位,然后将这 32 位转换回具有正确符号的整数。

Example 1:示例 1:

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

But the result should have been -1001297158 since converting '11000100010100010110101011111010' in a 32 bits integer is a negative number.但结果应该是 -1001297158,因为将 '11000100010100010110101011111010' 转换为 32 位整数是一个负数。

I already have my own solution:我已经有了自己的解决方案:

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

However, I would like to know if someone has a more elegant and performant idea.但是,我想知道是否有人有更优雅、更高效的想法。

Thank you in advance!先感谢您!

Significantly simpler solution: Let ctypes do the work for you.明显更简单的解决方案:让ctypes为您完成工作。

from ctypes import c_int32

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

That just constructs a c_int32 type from the provided Python int , which truncates as you desire, then extracts the value back out as a normal Python int type.这只是从提供的 Python int构造一个c_int32类型,它根据您的需要进行截断,然后将该值提取回正常的 Python int类型。 The time taken is less than that of your existing function for values that actually require trimming.对于实际需要修剪的值,所花费的时间少于现有函数的时间。 On my machine, it takes about 155-175 ns reliably, where your function is more variable, taking around 310-320 ns for positive values, and 405-415 ns for negative values.在我的机器上,它可靠地大约需要 155-175 ns,其中您的函数变化更大,正值需要大约 310-320 ns,负值需要 405-415 ns。

It is slower for values that don't require trimming though;但是对于不需要修剪的值,它更慢; your code excludes them relatively cheaply (I improved it slightly by changing the test to if -2 ** 31 <= val < 2 ** 31: ), taking ~75 ns, but this code does the conversion no matter what, taking the same roughly fixed amount of time.你的代码相对便宜地排除了它们(我通过将测试更改为if -2 ** 31 <= val < 2 ** 31: ),花费了大约 75 ns,但是这段代码无论如何都会进行转换,取同样大致固定的时间。 If numbers usually fit, and performance is critical, you can short cut out the way your original code (with slightly modification from me) did:如果数字通常适合,并且性能至关重要,您可以缩短原始代码(我稍作修改)的方式:

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

That makes the "must truncate" case slightly slower (just under 200 ns) in exchange for making the "no truncation needed" case faster (below 80 ns).这使得“必须截断”的情况稍微慢一些(不到 200 ns),以换取使“不需要截断”的情况更快(低于 80 ns)。

Importantly, either way, it's fairly simple.重要的是,无论哪种方式,它都相当简单。 It doesn't involve maintaining complicated code, and it's largely self-documenting;它不涉及维护复杂的代码,而且在很大程度上是自文档化的; you tell it to make a signed 32 bit int, and it does so.你告诉它生成一个有符号的 32 位 int,它就这样做了。

use bitstring library which is excellent.使用非常棒的位串库。

from bitstring import BitArray

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

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

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