I am making my own simple drawing engine. I am trying to determine if a variable has been set to a specific value using what I think is called bitwise comparison but I maybe wrong.
I've always been a bit confused about what the following is and how I use it:
int DRAW_REPEAT_X = 70001; // I have a feeling I should make this value binary instead of a unique number, ie, 0
int DRAW_REPEAT_Y = 70002; // I have a feeling I should make this value binary instead of a unique number, ie, 2
int drawMethod = DRAW_REPEAT_X | DRAW_REPEAT_Y; // this means I want to repeat an image on both the x and y axis doesn't it?
// Now I want to check if drawMethod has DRAW_REPEAT_X set: this is where I struggle to know how to check this
// Is the following correct?
if (drawMethod && DRAW_REPEAT_X) {
// the user wants me to repeat an image along the x axis
}
// Now I want to check if drawMethod has DRAW_REPEAT_Y set: this is where I struggle to know how to check this
if (drawMethod && DRAW_REPEAT_Y) {
// the user wants me to repeat an image along the x axis
}
Is the following code correctly checking if DRAW_REPEAT_X is set? It always returns 1 in my anding check.
EDIT And to check whether both bits are set do I do this?
if (drawMethod & DRAW_REPEAT_X & DRAW_REPEAT_Y) {
// both set
}
// OR
if (drawMethod & DRAW_REPEAT_X && drawMethod & DRAW_REPEAT_Y) {
// both set
}
No it isn't, you should use the bitwise AND operator instead - & and set the flags as binary values - your intuition is correct on that side.
A common trick to setting specific bits is using the shift operator:
int DRAW_REPEAT_X = 0x1 << 0; //first bit set to 1, others 0
int DRAW_REPEAT_Y = 0x1 << 1; //second bit set to 1, others 0
and check the int as
if (drawMethod & DRAW_REPEAT_X) //check it that particular flag is set, ignore others
{
}
For this to work, your flag variables each need to have a single, unique bit set. That bit is the "flag". For constants where it's the bitwise representation that matters, it's much more convenient to use hexadecimal or octal (because these bases are a power of 2) than decimal. So, for example:
enum {
DRAW_REPEAT_X = 0x01, /* First bit set */
DRAW_REPEAT_Y = 0x02, /* Second bit set */
DRAW_MIRRORED = 0x04, /* Third bit set */
};
int drawMethod = DRAW_REPEAT_X | DRAW_REPEAT_Y; /* Will have both first and second bits set */
Then you use bitwise-and & rather than logical-and && to test the bits. a & b will be non-zero if and only if there is at least one bit that is set in both a and b. In the case of testing for a flag, one of these will have only one bit set - the flag you're interested in - so the result of a & flag will be non-zero if and only if the flag is set in a:
if (drawMethod & DRAW_REPEAT_X) {
// the user wants me to repeat an image along the x axis
}
if (drawMethod & DRAW_REPEAT_Y) {
// the user wants me to repeat an image along the x axis
}
The hexadecimal pattern for constants with one bit set is 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, ...
As it stands right now, you aren't using flags so much as having a value that indicates a method. Much better is to use some sort of bits, like this:
int DRAW_REPEAT_X=0x01;
int DRAW_REPEAT_Y=0x02;
And then check the ifs like you are doing now, but with a single &
if (drawMethod & DRAW_REPEAT_X)
Typically, your integers (DRAW_REPEAT_X) should be public static, if you are working with a class architecture. But not knowing if that is the case, I won't include them
Here's a code snippet using the WinAPIs that shows setting two flags to a value, and then checking for the existence of at least one of those flags in that value. It should return 0;
INPUT mip;
mip.type = INPUT_MOUSE;
mip.mi.mouseData = 0;
mip.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
if (mip.mi.dwFlags & (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_HWHEEL))
return 0;
If you want to check for an exact value combination, you don't need to use the bitwise operator &, and can do a simple == check.
For example, the updated line near the bottom
INPUT mip;
mip.type = INPUT_MOUSE;
mip.mi.mouseData = 0;
mip.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
if (mip.mi.dwFlags == (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE))
return 0;
来源:https://stackoverflow.com/questions/13464063/check-if-flag-is-set-in-integer-variable