web-dev-qa-db-ja.com

Python

潜在的なビットマスクが次のようなバイト(他のベンダーからのもの)があります:

value1 = 0x01 value2 = 0x02 value3 = 0x03 value4 = 0x04 value5 = 0x05 value6 = 0x06 value7 = 0x40 value8 = 0x80

Value1からvalue6のいずれかが存在することを期待できます。そして、value7が設定される場合とされない場合があります。 value8は設定されている場合とされていない場合があります。

したがって、これは合法です。 value7 | value8これは不正です:value1 | value3 | value7

値7が設定されているか、値8が設定されているか、残りの値は何かを把握する必要があります。

私は次の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が大好きです。非常に多くの有用な答えが、とても迅速に!あなたたちは素晴らしいです!すべての答えに印を付けられたらいいのにと思います。しかし、私は少なくともみんなに賛成票を投じます!

EDIT2-以下の回答に基づいて、コードは次のように簡略化されます。

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()
9
Matthew Lund

value*定数のほとんどは実際にはビットマスクではなく、value7value8のみがビットマスクです。下位ビットを抽出するために別のビットマスクを定義するので、合計3つのビットマスクがあります。

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')
13
Sven Marnach

次のような値が与えられます:

>>> 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
5

他の2つの関数は必要ありません。

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
3
stew

少し冗長ですが、まったく問題ありません。私が行う唯一の変更は、parse_byteを単純化することです。

def parse_byte(byte):

     value7_set = byte & value7 == value7
     value8_set = byte & value8 == value8
     base_value = mask_bits_on_byte(byte,value7 | value8)
     return value7_set,value8_set,base_value  
1
Mark Ransom