私はCプログラミングにかなり慣れていない、そして私はビットマスキングに遭遇した。誰かが私にビットマスクの一般的な概念と機能を説明できますか?例は大歓迎です。
マスクはどのビットを保持し、どのビットをクリアするかを定義します。
マスキングは、値にマスクを適用することです。これは次のようにして達成されます。
以下は、値の中のビットのサブセットを抽出する例です。
Mask: 00001111b
Value: 01010101b
値にマスクを適用するということは、最初の(上位)4ビットをクリアし、最後の(下位)4ビットを保持したいということです。したがって、下位4ビットを抽出しました。年です。結果:
Mask: 00001111b
Value: 01010101b
Result: 00000101b
マスキングはANDを使って実装されているので、Cでは次のようになります。
uint8_t stuff(...) {
uint8_t mask = 0x0f; // 00001111b
uint8_t value = 0x55; // 01010101b
return mask & value;
}
これはかなり一般的なユースケースです。より大きなWordから個々のバイトを抽出する。 Wordの上位ビットを最初のバイトとして定義します。これには&
と>>
(右へシフト)という2つの演算子を使います。これが、32ビット整数から4バイトを抽出する方法です。
void more_stuff(uint32_t value) { // Example value: 0x01020304
uint32_t byte1 = (value >> 24); // 0x01020304 >> 24 is 0x01 so
// no masking is necessary
uint32_t byte2 = (value >> 16) & 0xff; // 0x01020304 >> 16 is 0x0102 so
// we must mask to get 0x02
uint32_t byte3 = (value >> 8) & 0xff; // 0x01020304 >> 8 is 0x010203 so
// we must mask to get 0x03
uint32_t byte4 = value & 0xff; // here we only mask, no shifting
// is necessary
...
}
上記の演算子の順序を入れ替えることができます。最初にマスクをしてからシフトを行うことができます。結果は同じですが、今度は別のマスクを使用する必要があります。
uint32_t byte3 = (value & 0xff00) >> 8;
マスキングは、情報の必要な部分を保持/変更/削除することを意味します。画像マスキング操作を見てみましょう。このマスキング操作は肌ではないものを取り除いています。
この例では、および操作をしています。他のマスキング演算子 - または、Xまたはもあります。
ビットマスキングは、ビットにマスクをかけることを意味します。これはと - によるビットマスキングです。
1 1 1 0 1 1 0 1 [input] (&) 0 0 1 1 1 1 0 0 [mask] ------------------------------ 0 0 1 0 1 1 0 0 [output]
したがって、(このマスクではこれらのビットは1
であるため)中央の4ビットのみが残ります。
これをXOR - で見てみましょう -
1 1 1 0 1 1 0 1 [input] (^) 0 0 1 1 1 1 0 0 [mask] ------------------------------ 1 1 0 1 0 0 0 1 [output]
これで、中央の4ビットが反転しました(1
は0
になり、0
は1
になりました)。
そのため、ビットマスクを使用して個々のビットにアクセスできます[ examples ]。時々、このテクニックはパフォーマンスを向上させるためにも使われるかもしれません。これを例にとると
bool isOdd(int i) {
return i%2;
}
この関数は、整数が奇数か偶数かを判断します。ビットマスクを使って同じ結果をより高い効率で達成することができます。
bool isOdd(int i) {
return i&1;
}
簡単な説明:2進数の 最下位ビット が1
の場合、それは奇数です。 0
の場合は偶数になります。そのため、1
でとを実行することで、最下位ビットを除く他のすべてのビットを削除します。
55 -> 0 0 1 1 0 1 1 1 [input] (&) 1 -> 0 0 0 0 0 0 0 1 [mask] --------------------------------------- 1 <- 0 0 0 0 0 0 0 1 [output]