Using Bitwise operators on flags

跟風遠走 提交于 2019-11-28 16:29:54

问题


I have four flags

Current = 0x1  
Past = 0x2  
Future = 0x4  
All = 0x7

Say I receive the two flags Past and Future (setFlags(PAST | FUTURE)). How can I tell if Past is in it? Likewise how can I tell that Current is not in it? That way I don't have to test for every possible combination.


回答1:


If you want all bits in the test mask to match:

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

If you want any single bit in the test mask to match:

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

The difference is most apparent when you are testing a value for multiple things.

To test for exclusion:

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



回答2:


First of all - use enums with FlagAttribute. That's what it's for.

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

Testing then is done like this:

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

Or this:

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

The latter will work better if "Past" was a combination of flags and you wanted to test them all.

Setting is like this:

x |= Time.Past;

Unsetting is like this:

x &= ~Time.Past;



回答3:


You may also want to add an extension method like this

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

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

then you can do:

 if(state.Is(states.Past)) {
    // Past
 }



回答4:


if ((flags & PAST) == PAST)
{
  // PAST is there
}

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



回答5:


If you use .NET 4 or later I prefer to do this, cleaner 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...
}



回答6:


An addendum to Marc Gravell and Vilx-'s answer:

Your flagged enum shouldn't specify the amount for "All", it should just include your existing values. This goes for any calculated values.

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

Note that Vilx- removed the use of Hexadecimal for values. This is important because once you're past 0x8, your values will have to comply with Hex. You should just stay in decimal.

EDIT: I also want to add that you can use bit shifting rather than hex/decimal.

This looks like:

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



回答7:


(value & Current) == Current



回答8:


you could use AND on it and check if the result is the same as you and with?



来源:https://stackoverflow.com/questions/530077/using-bitwise-operators-on-flags

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!