如何在Python中操作位?

时间:2020-03-06 14:51:46  来源:igfitidea点击:

例如,在C语言中,我可以将32位无符号值中的第10位清零,如下所示:

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

如何在Python中做到这一点?

解决方案

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

我们是否尝试过将代码复制并粘贴到Python REPL中以查看会发生什么?

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

省略" unsigned long",并且不需要分号:

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

Python具有C样式的位操作运算符,因此示例在Python中实际上是相同的,除了没有类型关键字。

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

对Python int进行按位运算的方式与C中的操作非常类似。Python中的||和^`运算符的用法与C中的用法相同。也就是说,〜x计算出-x-1.

我们必须对左移有所注意,因为Python整数不是固定宽度的。使用位掩码获取低阶位。例如,要等效于32位整数的移位,请执行((x << 5)&0xffffffff`。

如果我们要进行很多位操作(并且我们更关心可读性而不是应用程序的性能),则可能需要创建一个整数包装器来启用切片,例如在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

我们还应该签出BitArray,这是一个用于处理位序列的好接口。