Битовые операции

Логические И, ИЛИ, Исключающее ИЛИ, НЕ (AND, OR, XOR, NOT)

В побитовых операциях значение бита равное 1 рассматривается как логическая истина, а 0 — как ложь.

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

Логическое И (AND, оператор &)

Логическое умножение.

XYX AND Y
000
010
100
111

Результат дает 1, если все из сравниваемых значений равны 1.

Например, если логически умножить 2 на 4, то получим 0.

2: 0b00000010
4: 0b00000100
   ----------
0: 0b00000000

Логическое ИЛИ (OR, оператор |)

Логическое сложение.

XYX OR Y
000
011
101
111

Результат дает 1, если хотя бы одно из сравниваемых значений равно 1.

Например, если логически сложить 142 и 105, то получим 239

142: 0b10001110
105: 0b01101001
     ----------
239: 0b11101111

Исключающее ИЛИ (XOR, оператор ^)

XYX XOR Y
000
011
101
110

Результат дает 1, если только одно из сравниваемых значений равно 1.

Например, 12 и 53 дадут 57.

12: 0b00001100
53: 0b00110101
    ----------
57: 0b00111001

Логическое НЕ (NOT, оператор ~)

XNOT X
01
10

Результат дает 1, если значение было равно 0, и наоборот.

Например, 115 преобразуется в 140.

115: 0b01110011
     ----------
140: 0b10001100

Операции побитового сдвига

Битовый сдвиг влево (оператор <<)

Битовый сдвиг влево сдвигает биты влево, дописывая справа нули. Вышедшие за пределы числа биты отбрасываются.

0b01001011 << 2 == 0b00101100 

Для целых чисел операция равносильна умножению на 2.

Битовый сдвиг вправо (оператор >>)

Битовый сдвиг вправо сдвигает биты числа вправо, дописывая слева нули.

0b01001011 >> 2 == 0b00010010

Для целых чисел эта операция равносильна целочисленному делению пополам.

Примеры применения

Нумерация битов идет с права налево, первая позиция имеет номер 0.

Выставить определенный бит в 1

Просто применяем операцию побитового сдвига к единице в нужную нам позицию.

1 << position

В этом случае число 1 в левой части в двоичной системе будет представлено как 0b00000001. Запись просто единицы повышает читаемость кода.

И логически сложем нужное число и число, у которого все биты равны нулю, кроме нужного (начиная с нулевого).

Пример:
Нужно установить бит на позиции 4 в 1.

0b00100100 | (1 << 4) ==  0b00100100 | 0b00010000 == 0b00110100

Код (C):

int setbit(const int value, const int position) {
  return (value | (1 << position));
}

Для установки нескольких бит операцию следует повторить.

Код (C):

value |= (1 << position1) | (1 << position2) | (1 << position3);

Выставить определенный бит в 0

Умножим число на такое, у которого все биты равны единице, кроме бита под нужным номером.

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

Пример:
Нужно установить бит на позиции 4 в 0.

0b11010011 & ~(1 << 4) == 0b11010011 & ~(0b00010000) == 0b11010011 & 0b11101111 == 0b11000011

Код (C):

int unsetbit(const int value, const int position) {
  return (value & ~(1 << position));
}

Для установки нескольких бит в 0 операцию создание маски следует повторить.

value &= ~((1 << position1) | (1 << position2) | (1 << position3));

Изменить состояния бита в определенной позиции

Воспользуемся функцией Исключающего ИЛИ к числу, которое состоит из одних нулей и одной единицы на месте нужного бита.

Пример:
Нужно изменить состояния бита в позиции 4.

0b00000011 ^ (1 << 4) == 0b00000011 ^ 0b00010000 == 0b00010011

Код (C):

int switchbit(const int value, const int position) {
  return (value ^ (1 << position));
}

Для изменения нескольких бит создание маски следует повторить.

value ^= (1 << position1) | (1 << position2) | (1 << position3);

Узнать состояние бита в позиции

Для этого логически умножим наше число на проверочное число, у которого все биты равны нулю, кроме проверяемого (начиная с нулевого).

Пример:
Нужно узнать, выставлен ли бит на позиции 4 в 1.

0b00110100 & (1 << 4) == 0b00110100 & 0b00010000 == 0b0001000 == ИСТИНА
0b00100100 & (1 << 4) == 0b00100100 & 0b00010000 == 0b0000000 == ЛОЖЬ 

Код (C):

int checkbit(const int value, const int position) {
  return ((value & (1 << position)) != 0);
}

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *