このタスクを実行するコードをオンラインで見つけました。
byte = byte >> field;
byte = byte & 0x01;
return(byte);
ただし、これができない理由がわかりません。
return(byte & field);
これは機能しますか?なぜですか、そうでないのですか?より良い実装はありますか?
このタスクを実行するコードをオンラインで見つけました。
byte = byte >> field;
byte = byte & 0x01;
return(byte);
ただし、これができない理由がわかりません。
return(byte & field);
これは機能しますか?なぜですか、そうでないのですか?より良い実装はありますか?
最初のものは次のものと同等です:
return (byte >> field) & 0x01;
それが実際に行うことは、位置のあるビットにシフトし、そのビットが設定されている場合はfield
戻り、そうでない場合は戻ります。1
0
提案したものは、指定されたフィールドのオフセットにシフトしないため、正しくありません。たとえば、byte & 5
意味がありません。
関数は次のように書くこともできます:
return byte & (1 << field);
もちろん、1 << 5
の代わりに渡すつもりなら5
、あなたはそれをあなたのやり方で書くことができます。
field
関心のあるビットの位置を示す数値だと思います。したがって、1バイトの場合は範囲内になります0..7
。
最初のコードサンプルでは、fieldは、値が必要なフィールド内のビットの位置です。
2番目のサンプルでは、フィールドはそのビットが1に設定されたintである必要があります1 << field
。
field
右側からのワードのビット数(LSB)を表します。バイトbyte = byte >> field
のビット番号をLSB位置に持ってきます。次に、そのバイトは、元々ビット番号にビットが設定されていた場合はLSBにaが含まれ、その位置でビットがクリアされた場合は結果にaが含まれることを意味します。field
byte
byte = byte & 0x01
0x01
1
field
0
たとえば、バイト0x52
にビット番号4
が設定されているかどうかを確認するために必要なテストを以下に示します。
byte = 0x52 = 0 1 0 1 0 0 1 0
field = 0x04 = 0 0 0 0 0 1 0 0
Operation: byte = byte >> field
The bit number 4 is single quoted below. Note how it moves
intermediate byte | lost bits during
states | right shifting
byte = 0x52 = 0 1 0 '1' 0 0 1 0 |
shift 1 = 0x29 = 0 0 1 0 '1' 0 0 1 | 0
shift 2 = 0x14 = 0 0 0 1 0 '1' 0 0 | 1 0
shift 3 = 0x0A = 0 0 0 0 1 0 '1' 0 | 0 1 0
shift 4 = 0x05 = 0 0 0 0 0 1 0 '1' | 0 0 1 0
Note that the bit 4 is now moved at the LSB/righ most position of the byte
now if we test the rightmost position of the above byte then we can check
if the bit number 4 had its bit set or cleared, with the following operation
Operation: byte = byte & 0x01
byte is now 0x05
byte = 0x05 = 0 0 0 0 0 1 0 '1'
AND & & & & & & & &
0x01 = 0 0 0 0 0 0 0 1
---- ----------------
0x01 0 0 0 0 0 0 0 1
Now byte contains 0x01 so bit number 4 had the bit set. In the other case the
final answer would be 0.
ただし、番号が付けられているビットが設定またはクリアされているかどうかを確認することはできません。これは、が単なるバイナリであり、マスクではないためです。そうすると、次のことが起こります。byte & field
field
field
byte & field
byte = 0x52 = 0 1 0 1 0 0 1 0
AND & & & & & & & &
field = 0x04 = 0 0 0 0 0 1 0 0
---- ---------------
0x00 0 0 0 0 0 0 0 0
のfield
値0x04
は、ビット番号2
が設定されています。この操作で、ビット番号2
が設定されているかどうかを実際に確認しました。の値がfield
ビット5
で0
あり、が設定される場合、ビットの状態との値を2
抽出すると、上記のように直接ANDを実行すると、4つの可能な組み合わせが可能になります。0
2
byte
aのビット値をテストする他の方法は、それ自体をシフトbyte
する代わりに、マスク時間を左にシフトし、それをバイトとANDして、ゼロかどうかを確認することです。番号付きビットが設定されている場合はtrue、それ以外の場合はfalseになります。byte
0x01
field
(byte & (0x01 << field)) != 0
field
Operation: (0x01 << field)
Shifting 0x01 to the left field times field = 0x04 for the example
= 0x01 = 0 0 0 0 0 0 0 1
shift 1 = 0x02 = 0 0 0 0 0 0 1 0
shift 2 = 0x04 = 0 0 0 0 0 1 0 0
shift 3 = 0x08 = 0 0 0 0 1 0 0 0
shift 4 = 0x10 = 0 0 0 1 0 0 0 0
After the left shift the '1' moves in the bit position 4
Now we AND this with the byte to check if the bit position 4
is set or clear.
byte = 0x52 = 0 1 0 1 0 0 1 0
AND & & & & & & & &
(0x01 << field) = 0x10 = 0 0 0 1 0 0 0 0
---- ---------------
0x10 0 0 0 1 0 0 0 0
Therefore the answer (0x01 != 0) is 1 there fore the bit 4 is set. It the bit 4
was not set then the answer would be 0.
定期的にテストする必要がある特定の形式のバイトがある場合、たとえば、各ビットが特定のことを意味する事前定義された単語のビットフィールドがある場合は、特定のビット位置にのみ1つあるプリコンピューターマスクを保持できます。そのマスクでテストされます。たとえば、1バイトをチェックするには、プリコンピュータマスクは次のようになります。
#define BIT_0 0x01 //(00000001)
#define BIT_1 0x02 //(00000010)
#define BIT_2 0x04 //(00000100)
#define BIT_3 0x08 //(00001000)
#define BIT_4 0x10 //(00010000)
#define BIT_5 0x20 //(00100000)
#define BIT_6 0x40 //(01000000)
#define BIT_7 0x80 //(10000000)
したがって、ビット4をテストするには、次のbyte
ことを行うreturn (byte & BIT_4)
必要があります。return (byte & BIT_4) != 0;
ビット位置が何を表すかに応じて、マクロの名前を設定できます。
戻り値をゼロまたは1にしたい場合は、次のいずれかを実行できます
return ((byte & (1 << field)) != 0);
また
return ((byte >> field) & 0x01);
どちらの形式も、戻り値がゼロか非ゼロかだけを気にする場合、少し単純化されます。
1 番目の例では、必要なビットを戻り値の LSB に移動しますが、2 番目の例では、不要なすべてのビットを単純にマスクします。