2

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

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

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?在我的 anding 检查中它总是返回 1。

编辑 并检查是否设置了这两个位,我这样做吗?

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

// OR

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

4 回答 4

9

为此,您的每个标志变量都需要设置一个唯一的位。那一点是“标志”。对于重要的是按位表示的常量,使用十六进制或八进制(因为这些基数是 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 */

然后使用按位与&而不是逻辑与&&来测试位。 当且仅当在和a & b中都设置了至少一位时,它将是非零的。在测试标志的情况下,其中之一将只设置一个位 - 您感兴趣的标志 - 因此当且仅当标志设置为时,结果将非零:aba & flaga

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
}

设置一位常量的十六进制模式是0x01, 0x02, 0x04, 0x08, 0x10, 0x20, ...

于 2012-11-19T23:21:11.063 回答
8

不,不是,您应该改用按位 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
{
}
于 2012-11-19T23:12:36.253 回答
0

就目前而言,您并没有使用标志,而是使用指示方法的值。更好的是使用某种位,如下所示:

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

然后像你现在做的那样检查 ifs,但是用一个 &

if (drawMethod & DRAW_REPEAT_X)

通常,如果您使用的是类架构,您的整数 ( DRAW_REPEAT_X) 应该是。public static但不知道是不是这样,我不会包括他们

于 2012-11-19T23:14:36.247 回答
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;
于 2018-07-09T20:41:27.603 回答