私は独学でCを学ぼうとしています。私はこの演習に出くわし、それを理解するために勉強しています。マスキング ビットについて読みました。最後の 4 ビットを取得するには、val&0xF を実行する必要があります。この投稿も読みましたビット マスキングとは何ですか? . 説明が必要な部分は、可能な値が 0x7,0xB,0xD,0xE,0xF である理由です。私は答えを研究しており、さまざまな記事を読みました。誰かが私にこの部分を説明してくれるなら、私はそれを感謝します.
3 に答える
これらはすべて、最後の 4 ビットのうち少なくとも 3 ビットがオンになっている可能性のある数値だからです。0 から 15 までのすべての 2 進数を書き留めると、最後の 4 ビットのうち少なくとも 3 ビットが設定されていることがわかります。
- 0111 (0x7)
- 1011 (0xB)
- 1101 (0xD)
- 1110 (0xE)
- 1111 (0xF)
次のように考えてください: 0 から 6 までのすべての 2 進数には、最大で 2 ビットが設定されています。
- 0 (0)
- 1 (1)
- 10 (2)
- 11 (3)
- 100 (4)
- 101 (5)
- 110 (6)
したがって、どれもルールに一致しません。7 から 15 まで:
- 111 (7)
- 1000 (8)
- 1001 (9)
- 1010 (10)
- 1011 (11)
- 1100 (12)
- 1101 (13)
- 1110 (14)
- 1111 (15)
これらのうち、7、11、13、14、および 15 だけが、最後の 4 つのビット セットのうちの 3 つを持っています。
この方法は簡単に実装できます。
int chk_last_bits2(unsigned x) {
return ((x & 0x7) == 0x7) ||
((x & 0xB) == 0xB) ||
((x & 0xD) == 0xD) ||
((x & 0xE) == 0xE) ||
((x & 0xF) == 0xF);
}
ケースごとに明示的に等価性をテストする必要があることに注意してください。たとえば、いずれかのビットが設定されx & 0xB
ているすべての数値に対してゼロ以外の値を返します。1011
これは私たちが望んでいるものではありません。すべてをオンにして、平等にテストできるようにしたいのです。
別の可能な解決策は次のとおりです。
int chk_last_bits(unsigned x) {
int i, j;
for (i = 1, j = 0; i < 32; i <<= 1)
if (i & x)
j++;
return j >= 3;
}
あなたは C を学んでいるので、これはあなたが理解できるように残しておきます。
マスキングとは、ビットをフィルタリングし、関心のある一部のみを保持することを意味します。
something
変数と a がありmask
、どちらも値であるとしましょうunsigned
:something & mask
は、ビットが0
マスクの場所にある値と、マスクの場所にある0
値を返します。これはand マスクです。something
1
これらの特定の値を使用する理由を理解するには、C でビット演算 ( &
、|
...)がどのように機能するかを思い出す必要がa & b
あります。たとえば、a
is10001010
とb
is00000011
の場合、a & b
is 00000010
(orderly, 1 and 0, 0 and 0, 0 and 0, 0 and 0, 1 and 0, 0 and 0, 1 and 1, 0 and 1
) です。
それがわかれば、それらのマスクが何を選択するかを理解できます。それらのバイナリ表現を考えてみましょう:
0x7 --> ...00000111 --> the three LSBs 0xb --> ...00001011 --> the first, second and fourth LSBs 0xd --> ...00001101 --> the first, third and fourth LSBs 0xe --> ...00001110 --> the second, third and fourth LSBs 0xf --> ...00001111 --> the 4 LSBs
これは、値を抽出するためのマスキング用でした(リンクした回答を参照してください)。 xorやマスキングも同様に機能しますが、論理関数がどのように動作するかを思い出してください。