KingNestor
KingNestor

Reputation: 67960

How do you use bitwise flags in C++?

As per this website, I wish to represent a Maze with a 2 dimensional array of 16 bit integers.

Each 16 bit integer needs to hold the following information:

Here's one way to do it (this is by no means the only way): a 12x16 maze grid can be represented as an array m[16][12] of 16-bit integers. Each array element would contains all the information for a single corresponding cell in the grid, with the integer bits mapped like this:

alt text
(source: mazeworks.com)

To knock down a wall, set a border, or create a particular path, all we need to do is flip bits in one or two array elements.

How do I use bitwise flags on 16 bit integers so I can set each one of those bits and check if they are set.

I'd like to do it in an easily readable way (ie, Border.W, Border.E, Walls.N, etc).

How is this generally done in C++? Do I use hexidecimal to represent each one (ie, Walls.N = 0x02, Walls.E = 0x04, etc)? Should I use an enum?


See also How do you set, clear, and toggle a single bit?.

Upvotes: 11

Views: 14306

Answers (8)

Vinay
Vinay

Reputation: 4783

Use std::bitset    

Upvotes: 9

Znr4123
Znr4123

Reputation:

I'm not a huge fan of bitset. It's just more typing in my opinion. And it doesn't hide what you are doing anyway. You still have to & && | bits. Unless you are picking on just 1 bit. That may work for small groups of flags. Not that we need to hide what we are doing either. But the intention of a class is usually to make something easier for it's users. I don't think this class accomplishes it.

Say for instance, you have a flag system with .. 64 flags. If you want to test.. I don't know.. 39 of them in 1 if statement to see if they are all on... using bitfields is a huge pain. You have to type them all out.. Course. I'm making the assumption you use only bitfields functionality and not mix and match methods. Same thing with bitset. Unless I am missing something with the class.. which is quite possible since I rarely use it.. I don't see a way you can test all 39 flags unless you type out the hole thing or resort to "standard methods" (using enum flag lists or some defined value for 39 bits and using the bitsets && operator). This can start to get messy depending on your approach. And I know.. 64 flags sounds like a lot. And well. It is.. depending on what you are doing. Personally speaking, most of the projects I'm involved with depend on flag systems. So actually.. 64 is not that unheard of. Though 16~32 is far more common in my experience. I'm actually helping out in a project right now where one flag system has 640 bits. It's basically a privilege system. So it makes some sense to arrange them all together... However.. admittedly.. I would like to break that up a bit.. but.. eh... I'm helping.. not creating.

Upvotes: 0

xtofl
xtofl

Reputation: 41509

To manipulate sets of bits, you can also use ....

std::bitset<N>

std::bitset<4*4> bits;
bits[ 10 ] = false;
bits.set(10);
bits.flip();
assert( !bits.test(10) );

Upvotes: 2

KPexEA
KPexEA

Reputation: 16778

If you want to use bitfields then this is an easy way:

typedef struct MAZENODE
{
    bool backtrack_north:1;
    bool backtrack_south:1;
    bool backtrack_east:1;
    bool backtrack_west:1;
    bool solution_north:1;
    bool solution_south:1;
    bool solution_east:1;
    bool solution_west:1;
    bool maze_north:1;
    bool maze_south:1;
    bool maze_east:1;
    bool maze_west:1;
    bool walls_north:1;
    bool walls_south:1;
    bool walls_east:1;
    bool walls_west:1;
};

Then your code can just test each one for true or false.

Upvotes: 10

tkotitan
tkotitan

Reputation: 3009

Learn your bitwise opertors: &, |, ^, and !.

At the top of a lot of C/C++ files I have seen flags defined in hex to mask each bit.

#define ONE 0x0001

To see if a bit is turned on, you AND it with 1. To turn it on, you OR it with 1. To toggle like a switch, XOR it with 1.

Upvotes: 3

Evan Teran
Evan Teran

Reputation: 90422

Yes a good way is to use hex decimal to represent the bit patterns. Then you use the bitwise operators to manipulate your 16-bit ints.

For example:

if(x & 0x01){} // tests if bit 0 is set using bitwise AND
x ^= 0x02;     // toggles bit 1 (0 based) using bitwise XOR
x |= 0x10;     // sets bit 4 (0 based) using bitwise OR

Upvotes: 2

moonshadow
moonshadow

Reputation: 89055

Use hex constants/enums and bitwise operations if you care about which particular bits mean what.

Otherwise, use C++ bitfields (but be aware that the ordering of bits in the integer will be compiler-dependent).

Upvotes: 4

ChrisW
ChrisW

Reputation: 56083

You can do it with hexadecimal flags or enums as you suggested, but the most readable/self-documenting is probably to use what are called "bitfields" (for details, Google for C++ bitfields).

Upvotes: 1

Related Questions