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

Переменные типа int хранятся в двоичной системе счисления в виде последовательности бит. Биты нумеруются от 0, биты будем записывать справа налево (то есть бит с номером 0 будет записан самым правым, а самый старший бит — самым левым).

a = 0   # 0b0
a = 1   # 0b1
a = 2   # 0b10
a = 10  # 0b1010
a = 255 # 0b11111111

Например, если a = 10, то в битовой записи a биты с номерами 1 и 3 равны 1, а остальные биты равны 0.

В программах на языке Питон числа в двоичной системе счисления можно записывать в виде последовательностей из 0 и 1, предваряя их префиксом 0b. Например, допустимо присваивание a = 0b101.

Для двух переменных одинакового скалярного типа определены битовые операции:
& битовое И (AND)
| битовое ИЛИ (OR)
^ битовое ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR)
~ битовое ОТРИЦАНИЕ (NOT) — унарная операция.

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

a = 5     # 0b101
b = 6     # 0b110

c = a & b # 0b100 == 4
d = a | b # 0b111 == 7
e = a ^ b # 0b11 == 3
f =  ~ a  # 0b1...11111010 == -6

Битовое отрицание числа (величина f в последнем примере) — это число, полученное из исходного заменой всех нулей на единицы и наоборот.

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

Есть еще две операции, работающие с битами: это битовые сдвиги. Их два: сдвиг влево и вправо. Оператор a >> n возвращает число, которое получается из a сдвигом всех бит на n позиций вправо, при этом самые правые n бит отбрасываются. Например:

a = 43      # 0b101011
b = a >> 1  # 0b10101 == 21
c = a >> 2  # 0b1010 == 10
d = a >> 3  # 0b101 == 5
e = a >> 5  # 0b1 == 1

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

Аналогично, битовый сдвиг влево на n бит равносилен (для положительных чисел) умножению на 2n и осуществляется при помощи оператора <<:

a = 5       # 0b101
b = a << 1  # 0b1010 == 10
c = a << 2  # 0b10100 == 20
d = 2 << 3  # 0b101000 == 40

Таблица приоритетов операций в Python