Знакомство с логическими (побитовыми) операторами - Логические операторы

ОГЛАВЛЕНИЕ

Логические операторы

Существует шесть побитовых оператора:

   &   оператор И (AND)
   |   оператор ИЛИ (OR)
   ^   оператор XOR - исключающее ИЛИ, сложение по модулю 2
   ~   оператор инверсии
  >>   оператор сдвига вправо
  <<   оператор сдвига влево .

Оператор &

Оператор & (И) сравнивает два значения и возвращает значение 1, только в том случае, если оба значения были установлены в 1. Биты сравниваются используя следующую таблицу
   1   &   1   ==   1
   1   &   0   ==   0
   0   &   1   ==   0
   0   &   0   ==   0
Данный оператор лучше всего использовать для установки маски проверки значений определенных битов. Допустим, у нас есть байт (BYTE), который содержит некоторые битовые флаги, и мы хотим проверить, был ли четвертый бит установлен в единицу.
BYTE b = 50;
if ( b & 0x10 )
    cout << "Четвертый бит установлен" << endl;
else
    cout << "Четвертый бит читс" << endl;
В результате будет выполнен следующий подсчет
    00110010  - b
  & 00010000  - & 0x10
  ----------
    00010000  - результат
Теперь мы видим, что четвертый бит был установлен.

Оператор |

Оператор | (ИЛИ) сравнивает два значения и возвращает результат в виде единицы, если хотя бы один из битов будет установлен (равен единице). Биты сравниваются, используя следующую таблицу
   1   |   1   ==   1
   1   |   0   ==   1
   0   |   1   ==   1
   0   |   0   ==   0
Данный оператор лучше всего использовать для обеспечения установки каких-то определенных битов. Допустим, мы хотим убедиться, что значение третьего бита установлено
BYTE b = 50;
BYTE c = b | 0x04;
cout << "c = " << c << endl;
В результате будет выполнен следующий подсчет
    00110010  - b
  | 00000100  - | 0x04
  ----------
    00110110  - результат

Оператор ^

Оператор ^ (XOR) сравнивает два значения и возвращает единицу в случае, если значения сравниваемых элементов различаются. То есть в случае, если сравниваемые значения одинаковы, будет возвращено новое значение. Биты сравниваются, используя следующую таблицу
   1   ^   1   ==   0
   1   ^   0   ==   1
   0   ^   1   ==   1
   0   ^   0   ==   0
Идеальное использование такого оператора заключается в переключении определенных битов. Допустим, мы хотим изменить третий и четвертый бит
BYTE b = 50;
cout << "b = " << b << endl;
b = b ^ 0x18;
cout << "b = " << b << endl;
b = b ^ 0x18;
cout << "b = " << b << endl;
В результате будут выполнены следующие подсчеты
    00110010  - b
  ^ 00011000  - ^ 0x18
  ----------
    00101010  - result

    00101010  - b
  ^ 00011000  - ^ 0x18
  ----------
    00110010  - результат

Оператор ~

Оператор ~ (поразрядное дополнение или обратный код) действует только на одно значение и инвертирует его, преобразуя все единицы в нули, а нули -  единицы. Данный оператор используется для установления определенных бит в ноль и обеспечения того, что все другие биты установлены в единицу, независимо от размера данных. Допустим, мы хотим установить все биты в единицу, за исключением нулевого и первого бита:
BYTE b = ~0x03;
cout << "b = " << b << endl;
WORD w = ~0x03;
cout << "w = " << w << endl;
В результате будут выполнены следующие подсчеты
    00000011  - 0x03
    11111100  - ~0x03  b

    0000000000000011  - 0x03
    1111111111111100  - ~0x03  w
Другим вариантом использования является комбинация с оператором & для обеспечения того, что определенные биты установлены в нулевое значение. Допустим, мы хотим очистить четвертый бит
BYTE b = 50;
cout << "b = " << b << endl;
BYTE c = b & ~0x10;
cout << "c = " << c << endl;
В результате будут выполнены следующие подсчеты
    00110010  - b
  & 11101111  - ~0x10
  ----------
    00100010  - результат

Операторы >> и <<

Операторы >> (сдвиг вправо) и << (сдвиг влево) передвигают биты на определенное число позиций. Оператор >> сдвигает биты с бита с высоким уровнем к нижнему. Оператор << сдвигает биты со стороны нижнего уровня к биту с верхним уровнем. Одним из вариантов использования является выравнивание битов по какой-либо причине (ознакомьтесь с макросами MAKEWPARAM, HIWORD и LOWORD)
BYTE b = 12;
cout << "b = " << b << endl;
BYTE c = b << 2;
cout << "c = " << c << endl;
c = b >> 2;
cout << "c = " << c << endl;
В результате будут выполнены следующие подсчеты
    00001100  - b
    00110000  - b << 2
    00000011  - b >> 2