views:

161

answers:

3

There is a variable that holds some flags and I want to remove one of them. But I don't know how to remove it.

Here is how I set the flag.

my.emask |= ENABLE_SHOOT;
+18  A: 
my.emask &= ~(ENABLE_SHOOT);

to clear a few flags:

my.emask &= ~(ENABLE_SHOOT|SOME_OTHER|ONE_MORE);
Ned Batchelder
+6  A: 

Short Answer

You want to do an Bitwise AND operation on the current value with a Bitwise NOT operation of the flag you want to unset. A Bitwise NOT inverts every bit (i.e. 0 => 1, 1 => 0).

flags = flags & ~MASK; or flags &= ~MASK;.

Long Answer

ENABLE_WALK  = 0    // 00000000
ENABLE_RUN   = 1    // 00000001
ENABLE_SHOOT = 2    // 00000010
ENABLE_SHOOTRUN = 3 // 00000011

value  = ENABLE_RUN     // 00000001
value |= ENABLE_SHOOT   // 00000011 or same as ENABLE_SHOOTRUN

When you perform a Bitwise AND with Bitwise NOT of the value you want unset.

value = value & ~ENABLE_SHOOT // 00000001

you are actually doing:

      0 0 0 0 0 0 1 1     (current value)
   &  1 1 1 1 1 1 0 1     (~ENABLE_SHOOT)
      ---------------
      0 0 0 0 0 0 0 1     (result)

HTH,

Dennis

Dennis Roche
Your introductory paragraph should mention ANDing the inverted bits of the mask with the current value.
Jonathan Leffler
@JonathanLeffler: Thank-you for pulling that up. I quickly wrote the answer as I was stepping out for lunch.
Dennis Roche
Thanks for the answer
Aaron de Windt
@Aaron: I'm glad it helped. I initially had trouble understand bitwise operations *until* someone took 10 minutes to explain it on paper.
Dennis Roche
+3  A: 

It's important to note that if the variable being manipulated is larger than an int, the value used in the 'and not' expression must be as well. Actually, one can sometimes get away with using smaller types, but there are enough odd cases that it's probably best to use type suffixes to make sure the constants are large enough.

supercat
+1 for catching the nonobvious corner case. One way to avoid it is to instead use `flags -= flags ` (or `^=` if you prefer).
R..