2012-07-10 47 views
4

是否有更有效的方法來執行下面的計算?它工作正常,但有些事告訴我可以寫x &= (1 << 8) - 1^1 << 3以避免一些計算並提高速度。用BigInts創建一個位掩碼

def unset_mask(width, index): 
    return (1 << width) - 1^1 << index 

x = 0b11111111 
x &= unset_mask(8, 3) 
assert x == 0b11110111 

回答

3

其實,你並不需要國家的width。 Bigints行爲的正確方法,當你這樣做:

>>> bin(255 & ~(1 << 3)) 
'0b11110111' 
>>> bin(65535 & ~(1 << 3)) 
'0b1111111111110111' 
>>> bin(75557863725914323419135 & ~(1 << 3)) 
'0b1111111111111111111111111111111111111111111111111111111111111111111111110111' 

這是因爲負數有一個"infinite" string of ones preceding them。因此,當你補充一個正數(以「無限」字符串的零開始)時,你會得到一個負數(準確地說是-(x + 1))。只是不要相信bin表示負數;它並不反映內存中的實際位。

所以,你會重寫unset_mask像這樣:

def unset_mask(index): 
    return ~(1 << index) 

x = 0b11111111 
x &= unset_mask(3) 
print x == 0b11110111 # prints True 
+0

非常感謝!這是一個非常全面的答案和解釋。 – 2012-07-11 13:02:14

1

這將取消設置位:

x ^= 1 << 3 & x 

在功能:

def unset_bit(x, n): 
    return 1 << n & x^x 
+0

我不能讓它比這更短。 – 2012-07-11 07:43:54

1

您可以使用它來清除位x

x &= ~(1 << index)