2

次の列挙型マスキングがどのように機能するのか疑問に思いました

列挙型構造がある場合

public enum DelMask
{
        pass = 1,       
        fail = 2,       
        abandoned = 4,        
        distinction = 8,             
        merit = 16,        
        defer = 32,        
}

私は次のコードを見ました

int pass = 48;
if ((pass & (int)DelMask.defer) > 0)
   //Do something
else if ((pass & (int)DelMask.merit ) > 0)
   //Do something else

どのブロックがどのように実行されるかを誰かが理解するのを手伝ってくれるでしょうか?

4

5 に答える 5

3

ここで機能する基本的なビットロジック。整数48は、2進数で次のように終了します。

0011 0000

32歳の延期は次のとおりです。

0010 0000

16歳のメリットは次のとおりです。

0001 0000

ここで、論理積(&)を実行すると、結果のビットが両方とも入力の場所に設定されます。

pass & (int)DelMask.defer

0011 0000 
0010 0000
========= & 
0010 0000    

結果は16になるため((pass & (int)DelMask.defer) > 0)、trueと評価されます。両方ifのフラグが入力に存在するため、この例では両方がtrueと評価されます。2つ目は、であるため、評価されませんelse if

于 2012-11-01T11:15:31.707 に答える
1

どちらも正しいので、最初のものが実行されます。

16は10000です

32は100000です

48は16+32なので、110000です。

10000&110000は10000です

100000&110000は100000です

どちらもゼロより大きいです。

于 2012-11-01T11:13:41.183 に答える
1

48 = 16(メリット)+ 32(延期)。

したがってpass & (int)DelMask.defer、32と評価されるため、最初のブロックが実行されます。

そうでない場合は、pass & (int)DelMask.merit16と評価されるため、2番目のブロックがそこまで到達すると実行されます。

これが機能するのは、列挙型の値がすべて2の異なる累乗であり、基になるの独立したビットに対応しているためintです。これは、ビットフラグ列挙型として知られているものです。

于 2012-11-01T11:14:34.517 に答える
1

まず、int pass = 48; 基本的にこのコードは、数値の2進表現にビットが設定されているかどうかをチェックします。各&操作は、マスク内の場所にすべて0と1の結果を生成する必要があります。例えば:

48:         110000
defer = 32: 100000
            ______
          & 100000

したがって、次のコードを使用できます。

int pass = 48;
if ((pass & (int)DelMask.defer) == (int)DelMask.defer)
   //Do something
else if ((pass & (int)DelMask.merit ) == (int)DelMask.merit)
   //Do something else
于 2012-11-01T11:15:09.977 に答える
1

さて、あなたはそれらの数を2進数として考える必要があります。10進表記にはd接尾辞を使用し、2進表記にはb接尾辞を使用します。

列挙値:

  • 01d = 000001b
  • 02d = 000010b
  • 04d = 000100b
  • 08d = 001000b
  • 16d = 010000b
  • 32d = 100000b

パス値:

48d = 110000b

これで、&はビット単位のAND演算子になります。つまり、c = a&bの場合、aとbの両方でn番目のビットが1である場合に限り、cのn番目のビットは1になります。

それで:

  • 16d&48d = 010000b = 16d> 0
  • 32d&48d = 100000b = 32d> 0

ご覧のとおり、48dという数字は16dと32dの両方と「一致」しています。そのため、この種の列挙型は一般に「フラグ」列挙型として説明されます。1つの整数で複数の「フラグ」の値を持つことができます。

コードに関しては、最初のif演算子が検証されます。つまり、コードを入力して「何かをする」ということです。あなたは「何か他のことをする」ことはありません。

通常、C#では、フラグ列挙型に[Flags]属性を使用します。これにより、列挙型メンバーの10進値を実際に書き込むことができなくなります。いつものように、MSDNの例は役に立たないので、使用方法の詳細については、このSOの質問x & f == fを参照します(値xにフラグfが設定されているかどうかを知るには、またはx | f == xのいずれかを実行できますが、使用法は一般的に後者を使用するようです)。

于 2012-11-01T11:22:35.350 に答える