检查是否在整数变量中设置了标志

时间:2012-11-19 23:11:38

标签: c++ c bit-manipulation

我正在制作自己的简单绘图引擎。我正在尝试使用我认为称为按位比较的方式确定变量是否已设置为特定值,但我可能错了。

我一直对以下是什么以及如何使用它感到困惑:

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
}

以下代码是否正确检查是否设置了DRAW_REPEAT_X?在我的主题检查中它总是返回1。

修改的 并检查两个位是否都设置了吗?

if (drawMethod & DRAW_REPEAT_X & DRAW_REPEAT_Y) {
   // both set
}

// OR

if (drawMethod & DRAW_REPEAT_X && drawMethod & DRAW_REPEAT_Y) {
   // both set
}

4 个答案:

答案 0 :(得分:6)

不,不是,你应该使用按位AND运算符 - &并将标志设置为二进制值 - 你的直觉是正确的。

设置特定位的常用技巧是使用移位运算符:

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

并将int检查为

if (drawMethod & DRAW_REPEAT_X)  //check it that particular flag is set, ignore others
{
}

答案 1 :(得分:5)

为此,您的标志变量每个都需要有一个唯一的位集。那一点是“旗帜”。对于重要的按位表示的常量,使用十六进制或八进制(因为这些基数是2的幂)比使用十进制更方便。所以,例如:

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 */

然后使用bitwise-and &而不是logical-and &&来测试这些位。当且仅当至少有一个位在a & ba中设置时,b将为非零。在测试一个标志的情况下,其中一个只有一个位设置 - 你感兴趣的标志 - 所以a & flag的结果将是非零,当且仅当标志设置在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
}

设置一位的常量的十六进制模式为0x010x020x040x080x100x20 ,. ..

答案 2 :(得分:0)

现在看来,你没有使用标志,因为它有一个表示方法的值。更好的是使用某种位,如下所示:

int DRAW_REPEAT_X=0x01;
int DRAW_REPEAT_Y=0x02;

然后检查你现在正在做的ifs,但是只用一个&amp;

if (drawMethod & DRAW_REPEAT_X)

通常,如果使用类体系结构,则整数(DRAW_REPEAT_X)应为public static。但不知道是否是这种情况,我不会包括它们

答案 3 :(得分:0)

这是使用WinAPI的代码段,该代码段显示了将两个标志设置为一个值,然后检查该值中至少存在那些标志中的一个。它应该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;

如果要检查确切的值组合,则无需使用按位运算符&,并且可以执行简单的==检查。

例如,底部附近的更新行

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;