Простые логические операторы для битовых флагов - PullRequest
8 голосов
/ 16 ноября 2010

Я пытаюсь узнать больше об этом, чтобы реализовать в моем проекте.

В настоящее время я получил это в основном:

unsigned char flags = 0; //8 bits

flags |= 0x2; //apply random flag

if(flags & 0x2) {
   printf("Opt 2 set");
}

Теперь я хочу сделать немного более сложные вещи, я хочу применить три таких флага:

flags = (0x1 | 0x2 | 0x4);

А потом убрать с него флаги 0x1 и 0x2? Я думал, что мог бы сделать что-то вроде этого, применяя побитовое НЕ (и побитовое И, чтобы применить это):

flags &= ~(0x1 | 0x2);

Очевидно, они остаются там или что-то в любом случае, когда я проверяю.

Я также не знаю, как проверить, не существуют ли они в битовых флагах (поэтому я не могу проверить, работает ли мой предыдущий код), было бы что-то вроде этого?

if(flags & ~0x2) 
    printf("flag 2 not set");

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

Ответы [ 2 ]

22 голосов
/ 16 ноября 2010

А что два из него удалить? я думал Я мог бы сделать что-то вроде этого:

flags &= ~(0x1 | 0x2);

чтобы убрать эти два флага, но по-видимому, они остаются там или что-то в любом случае.

Это правильный способ удаления флагов. Если вы printf("%d\n", flags) после этой строки, вывод должен быть 4.

Я тоже не знаю, как проверить, они НЕ существуют в битовом флаге (так Я не могу проверить, если мой предыдущий код работает), было бы что-то вроде это? * * 1013

if(flags & ~0x2) 
    printf("flag 2 not set");

Нету:

if ((flags & 0x2) == 0)
    printf("flag 2 not set");

EDIT:

Чтобы проверить наличие нескольких флагов:

if ((flags & (0x1 | 0x2)) == (0x1 | 0x2))
    printf("flags 1 and 2 are set\n");

Чтобы проверить отсутствие нескольких флагов, просто сравните с 0, как и раньше:

if ((flags & (0x1 | 0x2)) == 0)
    printf("flags 1 and 2 are not set (but maybe only one of them is!)\n");
11 голосов
/ 16 ноября 2010

Я не уверен, почему вы думаете, что операция очистки не будет работать.

flags &= ~(0x1 | 0x2);

это правильный способ сделать это. Операция для проверки, установлен ли бит :

if (!(flags & 0x2)) ...

Тот, который у вас есть:

if (flags & ~0x2) ...

будет истинным, если установлен любой другой бит, поэтому, вероятно, вы решили, что операция очистки не работает. Проблема не в очистке, а в проверке.

Если вы хотите проверить, установлены ли все биты в группе:

if ((flags & (0x2|0x1)) == 0x2|0x1) ...
...