[英]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 ns),以換取使“不需要截斷”的情況更快(低於 80 ns)。
重要的是,無論哪種方式,它都相當簡單。 它不涉及維護復雜的代碼,而且在很大程度上是自文檔化的; 你告訴它生成一個有符號的 32 位 int,它就這樣做了。
使用非常棒的位串庫。
from bitstring import BitArray
x = BitArray(bin='11000100010100010110101011111010')
print(x.int)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.