Проверьте, установлен ли флаг в целочисленной переменной

Я делаю свой собственный простой движок рисования. Я пытаюсь определить, была ли переменная установлена ​​в определенное значение, используя то, что я думаю, называется побитовым сравнением, но я могу ошибаться.

Меня всегда немного смущало, что такое и как я это использую:

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
}

1

Решение

Нет, это не так, вы должны использовать побитовый оператор И вместо — & и установите флаги как двоичные значения — ваша интуиция верна с этой стороны.

Обычный трюк для установки определенных битов — использование оператора сдвига:

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

Затем вы используете поразрядно-и & а не логично && проверить биты. a & b будет отличным от нуля тогда и только тогда, когда в обоих a а также 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
}

Шестнадцатеричный шаблон для констант с одним установленным битом 0x01, 0x02, 0x04, 0x08, 0x10, 0x20

5

В нынешнем виде вы используете не столько флаги, сколько значение, указывающее на метод. Гораздо лучше использовать биты вроде этого:

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

А затем проверьте, если вы делаете сейчас, но с одним &

if (drawMethod & DRAW_REPEAT_X)

Как правило, ваши целые числа (DRAW_REPEAT_X) должно быть public static, если вы работаете с архитектурой класса. Но не зная, так ли это, я не буду их включать

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;
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector