Jump to content
  • Advertisement
Sign in to follow this  
Stormtrooper

Bitwise OR

This topic is 3799 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I was wondering exactly how the | operator works. Lets say I have an enumerator with different entries: First = 0, Second, Third, Forth. Is it possible to do something like: place = First | Second and store two values? What I'm trying to do is I have an array(C# BTW) the size of my tile map. I want to store attributes such as blocking a specific direction. I can either block only north, block only west...but what if I want to block both north and west? Would be a good idea to just have that as an attribute, or can I use the pipe operator to have two attributes in one variable?

Share this post


Link to post
Share on other sites
Advertisement
You can. Define NORTH as 1, EAST as 2, SOUTH as 4 and WEST as 8 (powers of two, each represented with a single 1 bit). Then, SOUTH | WEST means that both south and west are blocked. To determine if a given direction is blocked, use (0 != dir & blocked), for instance (0 != NORTH & blocked).

Share this post


Link to post
Share on other sites
The bitwise OR operator is not revertible in general. If a|b==1 and you know a==1, then you cannot conclude what the value of b is. But if a|b==1 and you know that a==0, then b must be 1. So, using the bitwise OR the way you want requires the values to not constribute both to the same bit digit. In other words, it works if you enumerate like
First = 0x1,
Second = 0x2,
Third = 0x4
and so on. Notice that each value occupies just one single bit that is not occupied by any other value. Furthurmore, a|0==a, so each value must differ from 0 to have an effect at all (i.e. each value must have (at least) one bit set).

Share this post


Link to post
Share on other sites
What ToohrVyk said, except he got the operator precedence wrong: You should test (0 != (dir & blocked)) instead, or simply (dir & blocked).

Share this post


Link to post
Share on other sites
If you have values starting at zero and increasing by one, you can use bit shifts to OR them:

#define NORTH 0
#define EAST 1
#define SOUTH 2
#define WEST 3

value= (1<<EAST)|(1<<SOUTH);

Share this post


Link to post
Share on other sites
To summarise the above, in C# you could do this:

[Flags]
enum Directions {
None = 0,
North = 1 << 0,
East = 1 << 1,
South = 1 << 2,
West = 1 << 3,
}

Directions D = Directions.North | Directions.West;

if ((D & Directions.North) != Directions.None) {
// North is set.
}
if ((D & Directions.East) != Directions.None) {
// East is set.
}
if ((D & Directions.South) != Directions.None) {
// South is set.
}
if ((D & Directions.West) != Directions.None) {
// West is set.
}

The [Flags] attribute modifies the behaviour of Directions.ToString() - in the above example, D.ToString() would return the string "North, West". Without the [Flags] attribute it would return "9".

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!