web-dev-qa-db-ja.com

フラグでのビット演算子の使用

私は4つの旗を持っています

_Current = 0x1  
Past = 0x2  
Future = 0x4  
All = 0x7
_

過去と未来の2つのフラグ(setFlags(PAST | FUTURE))を受け取ったとします。 Pastが含まれているかどうかはどうすればわかりますか?同様に、Currentが含まれていないことをどのように知ることができますか?そうすれば、考えられるすべての組み合わせをテストする必要はありません。

26
Malfist

テストマスクのすべてのビットを一致させたい場合:

if((value & mask) == mask) {...}

テストマスクの任意の1ビットを一致させたい場合:

if((value & mask) != 0) {...}

違いは、複数のものの値をテストするときに最も明白になります。

除外をテストするには:

if ((value & mask) == 0) { }
43
Marc Gravell

まず第一に-FlagAttributeで列挙型を使用します。それが目的です。

[Flags]
public enum Time
{
    None = 0
    Current = 1,
    Past = 2,
    Future = 4
    All = 7
}

次に、テストは次のように行われます。

if ( (x & Time.Past) != 0 )

またはこれ:

if ( (x & Time.Past) == Time.Past )

「過去」がフラグの組み合わせであり、それらすべてをテストしたい場合は、後者の方がうまく機能します。

設定は次のようになります。

x |= Time.Past;

設定解除は次のようになります。

x &= ~Time.Past;
29
Vilx-

拡張メソッドのように追加することもできます

  enum states {
     Current = 0x1,
     Past = 0x2,
     Future = 0x4,
     All = 0x7
  };

  static bool Is(this states current, states value) {
     return (current & value) == value;
  }

その後、あなたはすることができます:

 if(state.Is(states.Past)) {
    // Past
 }
12
Brian Rasmussen
if ((flags & PAST) == PAST)
{
  // PAST is there
}

if ((flags & CURRENT) != CURRENT)
{
  // CURRENT is not there
}
4
Misko

.NET 4以降を使用している場合は、これを実行することをお勧めします。よりクリーンなimao:

[Flags]
public enum Time
{
    None = 0
    Current = 1,
    Past = 2,
    Future = 4
}

myProp = Time.Past | Time.Future;

if (myProp.HasFlag(Time.Past))
{
    // Past is set...
}
3
Ogglas

Marc GravellとVilx-の回答の補遺:

フラグが立てられた列挙型は、「すべて」の量を指定するのではなく、既存の値を含める必要があります。これは、計算された値に当てはまります。

[Flags]
public enum Time
{
    None = 0,
    Current = 1,
    Past = 2,
    Future = 4,
    All = Current | Past | Future
}

Vilx-は値に16進数の使用を削除したことに注意してください。 0x8を超えると、値は16進数に準拠する必要があるため、これは重要です。 10進数のままにする必要があります。

EDIT: 1進数/ 10進数ではなくビットシフトを使用できることも追加したいと思います。

これは次のようになります。

[Flags]
public enum Time
{
    None = 0,
    Current = 1,
    Past = 1 << 1, // 2, 10 binary
    Future = 1 << 2, // 4, 100 binary
    All = Current | Past | Future
}
1
Kody
(value & Current) == Current
0