tengo un byte (de algún otro proveedor), donde las máscaras potenciales bits son los siguientes:bit de marca en Python
valor1 = 0x01 valor2 = 0x02 valor3 = 0x03 valor4 = 0x04 valor5 = 0x05 value6 = 0x06 value7 = 0x40 value8 = 0x80
Puedo contar con UNO de value1 a value6 presente. Y luego value7 puede o no establecerse. value8 puede o no establecerse.
Esto es legal: valor2 | valor7 | valor8 Esto no es legal: valor1 | valor3 | valor7
Necesito averiguar si el valor 7 está establecido, el valor8 está establecido y cuál es el valor restante.
Tengo el siguiente código python. ¿Hay una manera más elegante de hacer esto?
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. Tantas respuestas útiles, ¡tan rápido! Ustedes son increíbles! Ojalá pudiera marcar todas las respuestas. ¡Pero al menos les daré a todos un voto!
Edit2 - Sobre la base de las respuestas a continuación, el código se simplifica a la siguiente:
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()
Muy sucinto y aprecio el consejo sobre el zfill también. Utilizo el formato (valor, 'b'). Zfill (8) en todo el lugar, ahora puedo usar el formato (valor, '08b'). ¡Gracias por su respuesta! –
Como un lado, una forma fácil de hacer máscaras de bits con un buen código legible es escribirlas como 'value1 = 1 << 0',' value2 = 1 << 1' (etc). Es decir, tome un solo bit y simplemente cambie el cambio. Los errores son más obvios que con los literales hexadecimales o decimales. Si la máscara necesita varios bits, solo '|' los une (por ejemplo, 'value3 = (1 << 2) | (1 << 3)' en lugar de 'value3 = 0x0c'). – Kat