ORing arguments together
Hi, I'm a little confused on how ORing together arguments ( for example flags or options such as in Win32 (WM_MINIMIZED|WM_TOPMOST|WM_VISIBLE) ) I don't understand how that principle works, how can you combine three values together and then be able to uncombine them. For example lets say WM_MINIMIZED is 01h (or 1), WM_TOPMOST is 10h (2), and WM_VISIBLE is 11h (3), and if i OR them together the final result will be 11h. Which is the same as WM_VISIBLE. So how does the function that i pass these combined options knows that I passed 3 options and not just one WM_VISIBLE?
Well the answer is quite simple; you can't, not like that.
You need to think bitwise, not hex or decimal.
If you have 1, 10 and 100 for example, you can combine them with bitwise OR to 111. You can then use AND to check for specific bits.
Flags should generally be kept as single bits, otherwise some flags will simply override others.
You need to think bitwise, not hex or decimal.
If you have 1, 10 and 100 for example, you can combine them with bitwise OR to 111. You can then use AND to check for specific bits.
Flags should generally be kept as single bits, otherwise some flags will simply override others.
<edit>Oops, too slow :)</edit>
When this approach is taken, each option is a unique bit, e.g.
OPT1 = 0x1,
OPT2 = 0x2,
OPT3 = 0x4,
OPT4 = 0x8,
OPT5 = 0x10,
etc...
So OPT1 | OPT3 | OPT4 = binary(01101) = 0x0D
Then to test if an option is present, you could do:
OPTIONS = 0x06;
if( OPTIONS & OPT1 ) // 0x06 & 0x1 = 0 = false
//opt1 code
if( OPTIONS & OPT2 ) // 0x06 & 0x2 = 2 = true
//opt2 code
if( OPTIONS & OPT3 ) // 0x06 & 0x4 = 4 = true
//opt3 code
Hope that helps :)
When this approach is taken, each option is a unique bit, e.g.
OPT1 = 0x1,
OPT2 = 0x2,
OPT3 = 0x4,
OPT4 = 0x8,
OPT5 = 0x10,
etc...
So OPT1 | OPT3 | OPT4 = binary(01101) = 0x0D
Then to test if an option is present, you could do:
OPTIONS = 0x06;
if( OPTIONS & OPT1 ) // 0x06 & 0x1 = 0 = false
//opt1 code
if( OPTIONS & OPT2 ) // 0x06 & 0x2 = 2 = true
//opt2 code
if( OPTIONS & OPT3 ) // 0x06 & 0x4 = 4 = true
//opt3 code
Hope that helps :)
It works because those flags are designed to be ORed.
Let's consider 3 fictional flags, OPTION_1, OPTION_2, and OPTION_3.
These flags might be defined like this.
const int OPTION_1 = 1 << 0; // 1
const int OPTION_2 = 1 << 1; // 2
const int OPTION_3 = 1 << 2; // 4
When you pass a function the argument (OPTION_1 | OPTION_2 | OPTION_3), you're passing the binary value b111, or 7. As long as different flags are defined as powers of 2, they can be packed together as a single value.
Then to determine if OPTION_2 is set, for example, you would evaluate the statement (option & OPTION_2). When the two values are ANDed together, the bit representing OPTION_2 determines whether the statement returns true or false.
Let's consider 3 fictional flags, OPTION_1, OPTION_2, and OPTION_3.
These flags might be defined like this.
const int OPTION_1 = 1 << 0; // 1
const int OPTION_2 = 1 << 1; // 2
const int OPTION_3 = 1 << 2; // 4
When you pass a function the argument (OPTION_1 | OPTION_2 | OPTION_3), you're passing the binary value b111, or 7. As long as different flags are defined as powers of 2, they can be packed together as a single value.
Then to determine if OPTION_2 is set, for example, you would evaluate the statement (option & OPTION_2). When the two values are ANDed together, the bit representing OPTION_2 determines whether the statement returns true or false.
Typically each one is setting a certain bit in a DWORD. For instance..
FLAGA 0x00000001h;
FLAGB 0x00000002h;
FLAGC 0x00000004h;
FLAGD 0x00000008h;
FLAGE 0x00000016h;
You are ORing the bits together. so as you know (presumably) each of these in binary is:
FLAGA ...000001;
FLAGB ...000010;
FLAGC ...000100;
FLAGD ...001000;
FLAGE ...010000;
If I OR all of these together:
I would get ...011111; I can then AND the value with the certain flags to see if that particular bit is set.
Also 11h (doesn't equal 3) it equals 17 in hex. It would equal 3 if it were a binary representation.
I hope this helps.
USAGE
FLAGA 0x00000001h;
FLAGB 0x00000002h;
FLAGC 0x00000004h;
FLAGD 0x00000008h;
FLAGE 0x00000016h;
You are ORing the bits together. so as you know (presumably) each of these in binary is:
FLAGA ...000001;
FLAGB ...000010;
FLAGC ...000100;
FLAGD ...001000;
FLAGE ...010000;
If I OR all of these together:
I would get ...011111; I can then AND the value with the certain flags to see if that particular bit is set.
Also 11h (doesn't equal 3) it equals 17 in hex. It would equal 3 if it were a binary representation.
I hope this helps.
USAGE
DWORD FlagsSet = FLAGA | FLAGD; // FlagsSet = ...001001;CheckForFlags( FlagsSet ){ if (FlagsSet & FLAGA) //perform some action if (FlagsSet & FLAGB) //perform some action if (FlagsSet & FLAGC) //perform some action ... return ...;}
Quote:Original post by VanillaSnake21
Hi, I'm a little confused on how ORing together arguments ( for example flags or options such as in Win32 (WM_MINIMIZED|WM_TOPMOST|WM_VISIBLE) ) I don't understand how that principle works, how can you combine three values together and then be able to uncombine them. For example lets say WM_MINIMIZED is 01h (or 1), WM_TOPMOST is 10h (2), and WM_VISIBLE is 11h (3), and if i OR them together the final result will be 11h. Which is the same as WM_VISIBLE.
Think them more like flags that are either True(1) or False(0). With OR if any are true then the statement is true. So:
1 | 0 | 1 = 1
0 | 1 | 1 = 1
0 | 0 | 0 = 0
I wouldnt worry about trying to bitwise OR them, unless you really have to for an assigmnent or something. =)
Quote:
So how does the function that i pass these combined options knows that I passed 3 options and not just one WM_VISIBLE?
probably by Variable Length Arguments:
http://www.swig.org/Doc1.3/Varargs.html
You can pass multiple arguments to the same function.
Quote:
probably by Variable Length Arguments:
Nope, the functions in question use bitwise operations as previously observed. The "combined options" are really just a single parameter.
Thanks guys, i made a mistake in my OP, im currently doing assembly so im used to putting "h" at the end of numbers, i obviously meant to put "b" for binary. So basically the flags are meant to be ORed together? Then everything makes sense, I just didn't see how something like 1b, 10b, and 11b can be ORed unambiguously, but turns out they cant be. So i just have to use numbers that are a power of 2? Thanks for replies =D
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement