在Python位掩码 [英] Bit masking in Python
问题描述
我有个字节(从其他供应商),其中的潜在位掩码如下:
值1 = 0×01
值2 = 0×02
值3 = 0×03
值4 = 0×04
值5 = 0×05
value6 = 0×06
value7 = 0X40
value8 = 0x80的
我可以通过value6是present上值1的罪名。然后value7可以或可以不被设置。 value8可以或可以不被设置。
因此,这是合法的:VALUE2 | value7 | value8
这是不合法的:数值|值3 | value7
我要弄清楚值7是否设置,value8设置,什么剩余价值。
我有以下的蟒蛇code。有没有更优雅的方式来做到这一点?
值1 = 0×01
值2 = 0×02
值3 = 0×03
值4 = 0×04
值5 = 0×05
value6 = 0×06
value7 = 0X40
value8 = 0x80的高清format_byte_as_bits(值):
返回格式(价值,'B')。zfill(8)高清mask_bits_on_byte(字节,掩模):
inverse_of_mask = ^面膜0b11111111
返回字节和放大器; inverse_of_mask高清parse_byte(字节): value7_set =字节和放大器; value7 == value7
value8_set =字节和放大器; value8 == value8
字节= mask_bits_on_byte(字节,value7)
字节= mask_bits_on_byte(字节,value8)
BASE_VALUE =字节
返回value7_set,value8_set,BASE_VALUE#示例1
字节=值3 | value7
value7_set,value8_set,BASE_VALUE = parse_byte(字节)
打印(BASE_VALUE =+ STR(BASE_VALUE))
打印(value7_set =+ STR(value7_set))
打印(value8_set =+ STR(value8_set))
打印()#输出:
#BASE_VALUE = 3
#value7_set = TRUE
#value8_set =假#示例2
字节=值5
value7_set,value8_set,BASE_VALUE = parse_byte(字节)
打印(BASE_VALUE =+ STR(BASE_VALUE))
打印(value7_set =+ STR(value7_set))
打印(value8_set =+ STR(value8_set))
打印()#输出:
#BASE_VALUE = 5
#value7_set =假
#value8_set =假#示例3
字节=值| value7 | value8
value7_set,value8_set,BASE_VALUE = parse_byte(字节)
打印(BASE_VALUE =+ STR(BASE_VALUE))
打印(value7_set =+ STR(value7_set))
打印(value8_set =+ STR(value8_set))#输出:
#BASE_VALUE = 1
#value7_set = TRUE
#value8_set = TRUE
编辑 - 我爱计算器。因此,许多有用的答案,这么快!你们是真棒!希望我可以标记所有的答案。但我会至少给大家一个上一票!
EDIT2 - 基于下面的答案中,code简化为以下内容:
值1 = 0×01
值2 = 0×02
值3 = 0×03
值4 = 0×04
值5 = 0×05
value6 = 0×06
value7 = 0X40
value8 = 0x80的高清parse_byte(字节):
返回字节和放大器; value7,字节和放大器; 0x80的,字节和放大器; 7#示例1
字节=值3 | value7
value7_set,value8_set,BASE_VALUE = parse_byte(字节)
打印(BASE_VALUE =+ STR(BASE_VALUE))
如果value7_set:打印(value7_set)
如果value8_set:打印(value8_set)
打印()#示例2
字节=值5
value7_set,value8_set,BASE_VALUE = parse_byte(字节)
打印(BASE_VALUE =+ STR(BASE_VALUE))
如果value7_set:打印(value7_set)
如果value8_set:打印(value8_set)
打印()#示例3
字节=值| value7 | value8
value7_set,value8_set,BASE_VALUE = parse_byte(字节)
打印(BASE_VALUE =+ STR(BASE_VALUE))
如果value7_set:打印(value7_set)
如果value8_set:打印(value8_set)
打印()
你的大部分值*
常量实际上并没有位掩码,只有 value7
和 value8
是。我定义另一个位掩码来提取低位,所以我会在共有三个位掩码:
= MASK0 0x07执行
掩码1 = 0X40
MASK2 = 0x80的
现在您的功能变得
高清parse_byte(字节):
返回字节和放大器; MASK2,字节和放大器;掩码1,字节和放大器; MASK0
我没有转换结果布尔
- 我不明白为什么这应该是必要的。当检查与如果
返回的值,它会被隐式转换为布尔
反正。
还要注意的是
格式(价值,'B')。zfill(8)
可以简化为
格式(价值08B)
I have a byte (from some other vendor) where the potential bit masks are as follows:
value1 = 0x01 value2 = 0x02 value3 = 0x03 value4 = 0x04 value5 = 0x05 value6 = 0x06 value7 = 0x40 value8 = 0x80
I can count on ONE of value1 through value6 being present. And then value7 may or may not be set. value8 may or may not be set.
So this is legal: value2 | value7 | value8 This is not legal: value1 | value3 | value7
I need to figure out whether value 7 is set, value8 is set, and what the remaining value is.
I have the following python code. Is there a more elegant way to do this?
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
EDIT - I LOVE stackoverflow. So many useful answers, so quickly! You guys are awesome! Wish I could mark all the answers. But I'll at least give everyone an up vote!
EDIT2 - Based on the answers below, the code is simplified to the following:
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()
Most of your value*
constants aren't actually bit masks, only value7
and value8
are. I'd define another bit mask to extract the lower bits, so I would have three bit masks in total:
mask0 = 0x07
mask1 = 0x40
mask2 = 0x80
Now your function becomes
def parse_byte(byte):
return byte & mask2, byte & mask1, byte & mask0
I did not convert the results to bool
-- I don't see why this should be necessary. When checking the returned value with if
, it will be implicitly converted to bool
anyway.
Also note that
format(value,'b').zfill(8)
can be simplified to
format(value,'08b')
这篇关于在Python位掩码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!