1

フラグdefが存在します:

flag1=1
flag2=2
flag3=4
flag4=8
...
flagN=2^(N-1)

flag=flag1+flag2+...+flagN

設定されていない場合flagI、それはeq0

私は持っていflagます。たとえば、どのメソッドを簡単に確認できますflag2か?

4

4 に答える 4

4

各フラグでは、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

これはすべてのフラグで実行できます。

于 2012-08-05T08:50:55.410 に答える
4

ご質問への回答

の範囲は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 intin 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)
+-------------------------------+
于 2012-08-05T12:34:29.997 に答える
0
Boolean isSet (flags, flagN){
   Return (flags & flagN) != 0;
}

フラグはフラグベクトルであり、flagNはチェックしたいフラグです

于 2012-08-05T08:47:10.523 に答える
0

ビットマスクとフラグの概念をより深く理解する価値があります。次に、想像力を使って状態を効率的に表現できます。(以下で説明するのはほんの一例です)

 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 を実行し、上記の操作を評価します。

于 2012-08-05T09:54:19.967 に答える