私はCプログラミングにかなり慣れていないため、ビットマスキングに遭遇しました。誰かがビットマスキングの一般的な概念と機能を私に説明できますか?例は大歓迎です。
私は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;
}
これはかなり一般的なユースケースです:大きなワードから個々のバイトを抽出します。ワードの上位ビットを最初のバイトとして定義します。これには&
、と>>
(右シフト)の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;
&
ます。
#define MASK 0x000000FF .... my_uint32_t &= ~MASK
。
b
バイナリリテラルを示すためには、正しいすべてのコンパイラでサポートされていませんか?
マスキングとは、情報の必要な部分を保持/変更/削除することを意味します。画像マスキング操作を見てみましょう。のような-このマスキング操作は、皮膚でないものを削除しています-
この例では、AND演算を行っています。他のマスキング演算子-OR、XORもあります。
ビットマスキングとは、ビットにマスクを課すことを意味します。ここにANDを使用したビットマスキングがあります-
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]
したがって、中央の4ビットのみが1
残ります(これらのビットはこのマスクにあるため)。
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
)。
したがって、ビットマスクを使用して、個々のビットにアクセスできます[ 例 ]。場合によっては、この手法を使用してパフォーマンスを向上させることもできます。これを例にとると
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]