Python中的位掩码
我有一个字节(来自其他供应商),它的可能位掩码如下:
value1 = 0x01
value2 = 0x02
value3 = 0x03
value4 = 0x04
value5 = 0x05
value6 = 0x06
value7 = 0x40
value8 = 0x80
我可以确定 value1 到 value6 中至少有一个是存在的。而 value7 可能被设置,也可能没有。value8 也是如此。
所以像这样是合法的:value2 | value7 | value8
而这样就不合法:value1 | value3 | value7
我需要弄清楚 value7 是否被设置,value8 是否被设置,以及剩下的值是什么。
我有以下的 Python 代码。有没有更优雅的方法来实现这个?
value1 = 0x01
value2 = 0x02
value3 = 0x03
value4 = 0x04
value5 = 0x05
value6 = 0x06
value7 = 0x40
value8 = 0x80
def format_byte_as_bits(value):
return format(value,'b').zfill(8)
def mask_bits_on_byte(byte,mask):
inverse_of_mask = mask ^ 0b11111111
return byte & inverse_of_mask
def parse_byte(byte):
value7_set = byte & value7 == value7
value8_set = byte & value8 == value8
byte = mask_bits_on_byte(byte,value7)
byte = mask_bits_on_byte(byte,value8)
base_value = byte
return value7_set,value8_set,base_value
# Example 1
byte = value3 | value7
value7_set,value8_set,base_value = parse_byte(byte)
print("base_value = "+str(base_value))
print("value7_set = "+str(value7_set))
print("value8_set = "+str(value8_set))
print()
# Output:
# base_value = 3
# value7_set = True
# value8_set = False
# Example 2
byte = value5
value7_set,value8_set,base_value = parse_byte(byte)
print("base_value = "+str(base_value))
print("value7_set = "+str(value7_set))
print("value8_set = "+str(value8_set))
print()
# Output:
# base_value = 5
# value7_set = False
# value8_set = False
# Example 3
byte = value1 | value7 | value8
value7_set,value8_set,base_value = parse_byte(byte)
print("base_value = "+str(base_value))
print("value7_set = "+str(value7_set))
print("value8_set = "+str(value8_set))
# Output:
# base_value = 1
# value7_set = True
# value8_set = True
编辑 - 我太喜欢 StackOverflow 了。这里有这么多有用的答案,速度也很快!你们真棒!希望我能给所有答案都点赞。不过我至少会给每个人一个赞!
编辑2 - 根据下面的回答,代码简化为以下内容:
value1 = 0x01
value2 = 0x02
value3 = 0x03
value4 = 0x04
value5 = 0x05
value6 = 0x06
value7 = 0x40
value8 = 0x80
def parse_byte(byte):
return byte & value7, byte & 0x80, byte & 7
# Example 1
byte = value3 | value7
value7_set,value8_set,base_value = parse_byte(byte)
print("base_value = "+str(base_value))
if value7_set: print("value7_set")
if value8_set: print("value8_set")
print()
# Example 2
byte = value5
value7_set,value8_set,base_value = parse_byte(byte)
print("base_value = "+str(base_value))
if value7_set: print("value7_set")
if value8_set: print("value8_set")
print()
# Example 3
byte = value1 | value7 | value8
value7_set,value8_set,base_value = parse_byte(byte)
print("base_value = "+str(base_value))
if value7_set: print("value7_set")
if value8_set: print("value8_set")
print()
5 个回答
4
你不需要另外两个函数:
def parse_byte(byte):
value7_set = byte & value7 == value7
value8_set = byte & value8 == value8
base_value = byte & 7
return value7_set,value8_set,base_value
12
假设你有一个值,比如:
>>> x = 0b10001000
你可以通过下面的方式来检查高位的位是否被设置:
>>> bit8 = bool(x & 0b10000000)
>>> bit7 = bool(x & 0b01000000)
如果想找出哪个低位的位被设置了,可以用一个字典:
>>> bdict = dict((1<<i, i+1) for i in range(6))
>>> bdict[x & 0b00111111]
4
20
你定义的很多 value*
常量其实并不是位掩码,只有 value7
和 value8
是真正的位掩码。我建议再定义一个位掩码来提取低位,这样总共就会有三个位掩码:
mask0 = 0x07
mask1 = 0x40
mask2 = 0x80
现在你的函数变成了
def parse_byte(byte):
return byte & mask2, byte & mask1, byte & mask0
我没有把结果转换成 bool
类型——我觉得没有必要。因为在用 if
检查返回值的时候,它会自动转换成 bool
类型。
另外要注意的是
format(value,'b').zfill(8)
可以简化为
format(value,'08b')