Sign in to follow this  
CSharp_Padawan

bit masking for flags?

Recommended Posts

In C or C++ lets say I have several flags I want to pass into a function: doStuff( FLAG_ONE || FLAG_TWO || FLAG_THREE); This would be like some of the Windows API functions. How would I define the flags? How would I check in my functions which flags were sent in? I am really at a loss, but I think it has something to do with bit-masking. Any help is appreciated. CSharp_Padawan

Share this post


Link to post
Share on other sites
First of all, use a BINARY or, not a LOGICAL or.
So instead of
doStuff( FLAG_ONE || FLAG_TWO || FLAG_THREE);
write
doStuff( FLAG_ONE | FLAG_TWO | FLAG_THREE);

Define the flags like this:

in bits.h:

#ifndef BITS_H
#define BITS_H

enum Bits {
BIT7 = 0x80,
BIT6 = 0x40,
BIT5 = 0x20,
BIT4 = 0x10,
BIT3 = 0x08,
BIT2 = 0x04,
BIT1 = 0x02,
BIT0 = 0x01
};

#endif





in the other headers:

#ifndef MYFLAGS_H
#define MYFLAGS_H

#include <bits.h>

enum MyFlags {
FLAG_ONE = BIT3,
FLAG_TWO = BIT1,
FLAG_THREE = BIT7
};

#endif





Only define flags/bits that may be set. This prevents confusion.

Then you can use your flags like this:

char c;

// set a bit
c |= FLAG_ONE;

// clear a bit
c &= ~FLAG_TWO;

// check a flag
if (c & FLAG_THREE)
{
...
}


Share this post


Link to post
Share on other sites
Flags would be defined as a number that's a power of 2: 1, 2, 4, 8, 16, 32, 64... since each of these numbers represents a unique bit.

To extract a flag, you use a binary AND:

flags & FLAG_WHATEVER > 0

Also, you should be using the binary AND and OR operators (& and |) instead of the logical ones (&& and ||).

EDIT: darn, nmi beat me to it...

Share this post


Link to post
Share on other sites
Just to be nitpicky, I don't like using enums to define bit flags. They don't really buy you anything unless you define a symbol for every single combination of flags which is a pain in the neck and if you *don't* do that then when you try to make the flags map back to the enum it doesn't work which is confusing.

Share this post


Link to post
Share on other sites
Thanks for the replies!!!
Ratings++

Ok, I understand declaring the flags by powers of two. But I'm not certain I understand how to check which flags have been set.

It is just by using the bitwise AND ( & ) operator?

Quote:

// check a flag
if (c & FLAG_THREE)
{
...
}


I think I can do it now, but why does this work (I know enough about it to be dangerous[lol])?

Is this called bit-masking, or is that name sticking in my head from something else?

Thanks for the replies,
CSharp_Padawan

Share this post


Link to post
Share on other sites
Yup that's right and yup you can call it bitmasking.

If you picture these numbers in binary, this will be much easier. Bitwise & just goes through and makes a bit set only if that same bit is set in both numbers.


So: 010101011111010111
& 111001011101010001
= 010001011101010001

And in your example, if you want to check if a certain number has a bit set:

000101010101010110 <-- the number being passed in, we're assuming it could be anything
& 000000000000000100 <-- FLAG_THREE, that binary number is 4 in decimal
= 000000000000000100

huzzah! It gives a non-zero number. And C++ treats anything non-zero as 'true'.

Here's what it looks like if that bit is not set:
010010110101101000 <-- input
& 000000000000000100 <-- FLAG_THREE
= 000000000000000000

Everything is zero in the result, so C++ treats this as "false"


(edit: that binary number is 4 not 8)

[Edited by - pinacolada on May 26, 2005 7:00:23 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by jikbar
flags & FLAG_WHATEVER > 0


It might be safer to use "!= 0" instead of "> 0". This example code probably won't give the results you want.
	int x = 0xffffffff;
int y = 0x80000000;

if ( ( x & y ) > 0 )
{
cout << "( x & y ) > 0" << endl;
}
else
{
cout << "( x & y ) <= 0" << endl;
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this