Побитовый оператор — оператор для манипуляций с отдельными битами целого числа. То же: bitwise operator.
Вся современная цифровая электроника, как известно, основана на двоичной системе, где самая маленькая ячейка памяти может иметь значение 0 или 1 (нет сигнала или есть сигнал). Вся другая информация образуется сочетанием таких единичных сигналов. Десятеричное число 140, например, образуется следующим сочетанием нулей и единиц:
1> 2#10001100.
140
Первый бит отвечает за 128, второй — за 64, третий — за 32, четвёртый — за 16, пятый — за 8, шестой — за 4, седьмой — за 2, восьмой — за 1. Поэтому и получается, что 140 = 128 + 8 + 4.
Любое изменение информации сопровождается изменениями в битах (например, использование оператора сложения). Вот так число 140 поменяется, если к нему добавить 1:
1> io:format("~.2# ~n", [140+1]).
2#10001101
Но иногда хочется более явно воздействовать на биты числа. Для этого и существуют побитовые операторы.
В обоих числах сравниваются биты: первые биты, вторые биты и т.д. Если оба биты равны 1, значит, в итоговом числе на этой позиции тоже будет 1. В противном случае будет 0.
1> X = 2#11010101.
213
2> Y = 2#11001100.
204
3> io:format("~.2# ~n", [X band Y]).
2#11000100
ok
4> io:format("~.10# ~n", [X band Y]).
10#196
ok
Вот так из чисел 213 и 204 мы получили 196. Если угодно, мы можем это проверить:
5> 213 band 204 == 196.
true
Биты сравниваются аналогично. Но сейчас если оба биты равны 0, значит, в итоговом числе на этой позиции тоже будет 0. В противном случае будет 1. Иными словами, если хотя бы в одной ячейке будет 1, значит в итоговой тоже будет 1.
11110000
bor
10101010
—-------
11111010
Если биты одинаковые, в итоге будут нули. Если разные — единицы.
11110000
bxor
10101010
—-------
01011010
Это унарный оператор. Каждый бит меняет значение на противоположный: 0 на 1, 1 на 0.
1> io:format("~p ~n", [bnot 2#10001100]).
-141
Первый операнд — число, над которым проводим манипуляции. Второй операнд — количество битов, на которое сдвигаем первое число.
1> io:format("~.2# ~n", [2#10001100 bsl 1]).
2#100011000
ok
2> io:format("~.10# ~n", [2#10001100 bsl 1]).
10#280
ok
Вот так мы сдвинули биты на 1 позицию влево, и число 140 превратилось в 280. Раз каждый бит сместился на более старшую позицию (в 2 раза), значит, и всё число увеличилось тоже в 2 раза. Если сместим на 3 позиции, то итоговое число будет в 8 раз больше.
3> io:format("~.2# ~n", [2#10001100 bsl 3]).
2#10001100000
ok
4> io:format("~.10# ~n", [2#10001100 bsl 3]).
10#1120
ok
Если в исходном числе был байт (восемь бит), то стало 11, потому что мы добавили 3 бита. Все добавляемые биты — нули.
Правый операнд может быть отрицательным числом, и тогда bsl работает как bsr, то есть биты сдвигаются вправо.
5> io:format("~.2# ~n", [2#10001100 bsl -3]).
2#10001
ok
Работает как bsl, только сдвигает вправо.
© Алексей Карманов, 2024.