2008-09-29 45 views
28

在C,我可以,例如,零出位#10在32位無符號值,像這樣:如何操作Python中的位?

unsigned long value = 0xdeadbeef; 
value &= ~(1<<10); 

如何做到這一點在Python?

回答

42

Python ints上的按位操作與C中的操作非常相似。和Python中的^運算符就像在C中一樣工作。〜運算符與C中的有符號整數一樣工作;即〜x計算-x-1。

由於Python整數不是固定寬度,所以你必須對左移有點小心。使用位掩碼來獲取低位位。例如,做一個32位整數移位的等價做(x < < 5)& 0xffffffff。

11
value = 0xdeadbeef 
value &= ~(1<<10) 
3

您是否嘗試過將代碼複製並粘貼到Python REPL中以查看會發生什麼?

>>> value = 0xdeadbeef 
>>> value &= ~(1<<10) 
>>> hex (value) 
'0xdeadbaef' 
3

略去unsigned long類型,並且不需要分號之一:

value = 0xDEADBEEF 
value &= ~(1<<10) 
print value 
"0x%08X" % value 
3

Python有空調風格位處理運算符,所以你的例子是字面上只是沒有在Python一樣鍵入關鍵字。

value = 0xdeadbeef 
value &= ~(1 << 10) 
0

如果您要做很​​多位操作(並且您更關心可讀性而不是應用程序的性能),那麼您可能需要創建一個整數封裝來啓用像Verilog或VHDL一樣的分片:

 
import math 
class BitVector: 
    def __init__(self,val): 
     self._val = val 

    def __setslice__(self,highIndx,lowIndx,newVal): 
     assert math.ceil(math.log(newVal)/math.log(2)) <= (highIndx-lowIndx+1) 

     # clear out bit slice 
     clean_mask = (2**(highIndx+1)-1)^(2**(lowIndx)-1) 

     self._val = self._val^(self._val & clean_mask) 
     # set new value 
     self._val = self._val | (newVal<<lowIndx) 

    def __getslice__(self,highIndx,lowIndx): 
     return (self._val>>lowIndx)&(2L**(highIndx-lowIndx+1)-1) 

b = BitVector(0) 
b[3:0] = 0xD 
b[7:4] = 0xE 
b[11:8] = 0xA 
b[15:12] = 0xD 

for i in xrange(0,16,4): 
    print '%X'%b[i+3:i] 

輸出:

 
D 
E 
A 
D 
4

您也應該檢查出BitArray,這是一個很好的接口來處理的比特序列。

0
a = int('00001111', 2) 
b = int('11110000', 2) 
bin(a & b)[2:].zfill(8) 
bin(a | b)[2:].zfill(8) 
bin(a << 2)[2:].zfill(8) 
bin(a >> 2)[2:].zfill(8) 
bin(a^b)[2:].zfill(8) 
int(bin(a | b)[2:].zfill(8), 2)