mam bajt (od innego producenta), w których potencjalne maski bitowe są następujące:bitów maskowania Pythona
wartosc1 = 0x01 wartość2 = 0x02 wartość3 = 0x03 value4 = 0x04 value5 = 0x05 wartość6 = 0x06 wartość7 = 0x40 wartość8 = 0x80
Mogę liczyć na JEDEN z wartości1 do wartości6 obecnych. A następnie wartość7 może lub nie może być ustawiona. wartość 8 może lub nie może być ustawiona.
To jest legalne: wartość2 | wartość7 | value8 To nie jest legalne: wartość1 | wartość3 | value7
Muszę dowiedzieć się, czy ustawiono wartość 7, ustawiono wartość 8 i jaka jest pozostała wartość.
Mam następujący kod Pythona. Czy istnieje bardziej elegancki sposób na zrobienie tego?
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
EDYCJA - I LOVE stackoverflow. Tak wiele przydatnych odpowiedzi, tak szybko! Jesteście niesamowici! Chciałbym zaznaczyć wszystkie odpowiedzi. Ale przynajmniej dam wszystkim głos w górę!
EDIT2 - Na podstawie poniższych odpowiedzi, kod jest uproszczone do następującego:
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()
Bardzo zwięzłe i doceniam również wskazówkę na temat zfill. Używam formatu (wartość, "b"). Zfill (8) wszędzie, teraz mogę po prostu użyć formatu (wartość, "08b"). Dzięki za twoją odpowiedź! –
Na marginesie, prostym sposobem tworzenia poprawnych bitmask z ładnym czytelnym kodem jest zapisanie ich w stylu 'value1 = 1 << 0',' value2 = 1 << 1' (etc). To znaczy, weź jeden kawałek i po prostu zmień przesunięcie. Błędy są bardziej oczywiste niż w przypadku liter heksadecymalnych lub dziesiętnych. Jeśli maska wymaga zestawu wielu bitów, po prostu '|' te razem (np. 'Wartość3 = (1 << 2) | (1 << 3)' zamiast 'wartość3 = 0x0c'). – Kat