フラグdefが存在します:
flag1=1
flag2=2
flag3=4
flag4=8
...
flagN=2^(N-1)
flag=flag1+flag2+...+flagN
設定されていない場合flagI
、それはeq0
私は持っていflag
ます。たとえば、どのメソッドを簡単に確認できますflag2
か?
フラグdefが存在します:
flag1=1
flag2=2
flag3=4
flag4=8
...
flagN=2^(N-1)
flag=flag1+flag2+...+flagN
設定されていない場合flagI
、それはeq0
私は持っていflag
ます。たとえば、どのメソッドを簡単に確認できますflag2
か?
各フラグでは、1 ビットのみが 1 に設定され、他のビットは 0 に設定されることに注意してください。
flag1 = 000 ... ... 0001
flag2 = 000 ... ... 0010
flag3 = 000 ... ... 0100
// and like this
したがって、ビット単位の AND を実行すると、が定義されているflag & flag2
場合にのみ、結果が非ゼロになります。flag2
r = flag & flag2;
if r != 0 then flag2 is defined
これはすべてのフラグで実行できます。
の範囲はflag
?2^64-1 未満であれば、ほとんどすべての方法で問題ありません。
@taskinoor が投稿したように、次のことに注意してください。
flag1 = 000 ... ... 0001 flag2 = 000 ... ... 0010 flag3 = 000 ... ... 0100
言い換えると、
flag[n] = 1 << (n-1)
したがって、すべてのビットをチェックしたい場合は、for
ループとbitwise operation
問題を解決するのに十分な速さです。このように ( C/C++を理解でき、 flag が 2^32 未満であり、unsigned int
in C/C++で保持できるとします):
void check(unsigned int flag)
{
for (int i = 0; i < 32; ++i)
if ((flag & (1 << i)) != 0)
printf("flag%d defined!\n", i+1);
}
flag
それは O(k) で、k はバイナリの型の長さです。の場合unsigned int
、ほぼ一定時間で O(32) = O(1) です。
あなたの目的が何なのかわかりません。定義されたフラグの数を数えたいだけflag
で、2 ^ 64 未満である場合は、次の方法が素晴らしいです (同様に仮定unsigned int
します)。
unsigned int count_bit(unsigned int x)
{
x = (x & 0x55555555) + ((x >> 1) & 0x55555555);
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
x = (x & 0x0F0F0F0F) + ((x >> 4) & 0x0F0F0F0F);
x = (x & 0x00FF00FF) + ((x >> 8) & 0x00FF00FF);
x = (x & 0x0000FFFF) + ((x >> 16)& 0x0000FFFF);
return x;
}
count_bit(1234567890) を呼び出すと、12 が返されます。
このアルゴリズムについて説明します。
このアルゴリズムは に基づいていDivide and Conquer Algorithm
ます。8 ビット整数 213 (バイナリで 11010101) があると仮定すると、アルゴリズムは次のように機能します (毎回 2 つの隣接ブロックをマージします)。
+-------------------------------+
| 1 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | <- x
| 1 0 | 0 1 | 0 1 | 0 1 | <- first time merge
| 0 0 1 1 | 0 0 1 0 | <- second time merge
| 0 0 0 0 0 1 0 1 | <- third time ( answer = 00000101 = 5)
+-------------------------------+
Boolean isSet (flags, flagN){
Return (flags & flagN) != 0;
}
フラグはフラグベクトルであり、flagNはチェックしたいフラグです
ビットマスクとフラグの概念をより深く理解する価値があります。次に、想像力を使って状態を効率的に表現できます。(以下で説明するのはほんの一例です)
First -Define the bitmask : 0x0000001c
マスクに対して「and」演算を実行すると、ゼロ以外の値が得られるバイナリ文字列は何ですか?
これらは有効なフラグ値です。
このビットマスクの有効なフラグ値: 0x0000001c,0x00000014,0x00000018,0x00000004,0x00000008,etc ..
したがって、アプリケーションで次のことができる場合:
flagvariable |= flagvalue1 ->Enable a particular flag.
if( flagvariable & maskvalue) :Check if a mask is enabled :
次に、チェックする必要があるさまざまなケース:
if(flagvariable &maskvalue ==flagvalue1) { do something}
else
if(flagvariable &maskvalue ==flagvalue2) {do something else}
flagvariable &= `flagvalue1 : Clear the flag
フラグとビットマスクについてより明確にするために、gdb にステップインして p /t を実行し、上記の操作を評価します。