Побитовые операторы

Описание, примеры

Побитовые операторы интерпретируют операнды как последовательность из 32 битов (нулей и единиц). Они производят операции, используя двоичное представление числа и возвращают новую последовательность из 32 бит (число) в качестве результата.

В следующей таблице перечислены все побитовые операторы.
Далее двоичное представление числа и операторы разобраны более подробно.

Оператор Использование Описание
Побитовое И (AND) a & b Ставит 1 на каждого бита результата, для которого соответствующие биты операндов равны 1.
Побитовое ИЛИ (OR) a | b Ставит 1 для каждого бита результата, для которого хотя бы один из соответствующих битов операндов равен 1.
Побитовое исключающее ИЛИ (XOR) a ^ b Ставит 1 для каждого бита результата, для которого только один(но не оба) из соответствующих битов операндов равен 1.
Побитовое НЕ (NOT) ~ a Заменяет каждый бит операнда на противоположный.
Левый сдвиг a << b Сдвигает двоичное представление a на b битов влева, добавляя справа нули.
Правый сдвиг, переносящий знак a >> b Сдвигает двоичное представление a на b битов вправо, отбрасывая сдвигаемые биты.
Правый сдвиг с заполнением нулями a >>> b Сдвигает двоичное представление a на b битов вправо, отбрасывая сдвигаемые биты и добавляя нули слева.

Формат 32-битного целого числа со знаком

Операнды всех побитовых операндов интерпретируются как 32-битные целые числа со знаком и старшим битом слева и дополнением до двойки.

"Старший бит слева" - означает, что самый значимый бит (битовая позиция с самым большим значением) находится на крайнем левом месте.

"Дополнение до двойки" означает, что двоичный вид числа, обратного данному (например, 5 и -5) получается путем обращения(двоичного НЕ) всех битов с добавлением 1.

Например, вот число 314:

00000000000000000000000100111010

Чтобы получить -314, первый шаг - обратить биты числа:

11111111111111111111111011000101

Второй шаг - прибавить единицу:

11111111111111111111111011000110

Принцип дополнения до двойки делит все двоичные представления на два множества: если крайний-левый бит равен 0 - число положительное, если 1 - число отрицательное. Поэтому этот бит называется знаковым битом.

Побитовые операции

Бинарные побитовые операторы работают следующим образом:

  • Операнды преобразуются в 32-битные целые числа, представленные последовательностью битов (нулей и единиц)
  • Каждый бит в первом операнде рассматривается вместе с соответствующим битом второго операнда: первый бит с первым, второй со вторым и т.п.
  • Оператор применяется к каждой паре бит, давая соответствующий бит результата.

& (побитовое И)

Выполняет операцию И над каждой парой бит. a И b равно единице только когда оба бита равны единице.

Таблица истинности для И:

a b a И b
0 0 0
0 1 0
1 0 0
1 1 1
Пример:
Выделить все
9 (по осн. 10) 
  = 00000000000000000000000000001001 (по осн. 2)
14 (по осн. 10) 
  = 00000000000000000000000000001110 (по осн. 2)
                   --------------------------------
14 & 9 (по осн. 10) 
  = 00000000000000000000000000001000 (по осн. 2) 
  = 8 (по осн. 10)

| (Побитовое ИЛИ)

Выполняет операцию ИЛИ над каждой парой бит. a ИЛИ b равно 1, если хотя бы один бит из a,b равен 1.

Таблица истинности для ИЛИ:

a b a ИЛИ b
0 0 0
0 1 1
1 0 1
1 1 1
Пример:
Выделить все
9 (по осн. 10) 
  = 00000000000000000000000000001001 (по осн. 2)
14 (по осн. 10)
  = 00000000000000000000000000001110 (по осн. 2)
                   --------------------------------
14 | 9 (по осн. 10) 
  = 00000000000000000000000000001111 (по осн. 2) 
  = 15 (по осн. 10)

^ (Исключающее ИЛИ)

Выполняет операцию исключающего ИЛИ над каждой парой бит.
a Исключающее ИЛИ b равно 1, если только a=1 или только b=1, но не оба одновременно a=b=1.

Таблица истинности для исключающего ИЛИ:

a b a Исключающее ИЛИ b
0 0 0
0 1 1
1 0 1
1 1 0
Пример:
Выделить все
9 (по осн. 10) 
  = 00000000000000000000000000001001 (по осн. 2)
14 (по осн. 10) 
  = 00000000000000000000000000001110 (по осн. 2)
                   --------------------------------
14 ^ 9 (по осн. 10) 
  = 00000000000000000000000000000111 (по осн. 2) 
  = 7 (по осн. 10)

~ (Побитовое НЕ)

Производит операцию НЕ над каждым битом, заменяя его на обратный ему.

Таблица истинности для НЕ:

a НЕ a
0 1
1 0
Пример:
Выделить все
9 (по осн. 10) 
  = 00000000000000000000000000001001 (по осн. 2)
               --------------------------------
~9 (по осн. 10) 
  = 11111111111111111111111111110110 (по осн. 2) 
  = -10 (по осн. 10)

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

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

Направление сдвига - то же, что и направление стрелок в операторе.

<< (Левый сдвиг)

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

Например, 9 << 2 даст 36:

Пример:
Выделить все
9 (по осн.10)
  = 00000000000000000000000000001001 (по осн.2)
                  --------------------------------
9 << 2 (по осн.10)
  = 00000000000000000000000000100100 (по осн.2) 
  = 36 (по осн.10)

>> (Правый сдвиг, переносящий знак)

Этот оператор сдвигает биты вправо, отбрасывая лишние. Копии крайнего-левого бита добавляются слева. Так как итоговый крайний-левый бит имеет то же значение, что и исходный, знак числа (представленный крайним-левым битом) не изменяется.

Поэтому он назван "переносящим знак".

Например, 9 >> 2 даст 2:

Пример:
Выделить все
9 (по осн.10)
  = 00000000000000000000000000001001 (по осн.2)
                  --------------------------------
9 >> 2 (по осн.10)
  = 00000000000000000000000000000010 (по осн.2) 
  = 2 (по осн.10)

Аналогично, -9 >> 2 даст -3, так как знак сохранен:

Пример:
Выделить все
-9 (по осн.10)
  = 11111111111111111111111111110111 (по осн.2)
                   --------------------------------
-9 >> 2 (по осн.10)
  = 11111111111111111111111111111101 (по осн.2) = -3 (по осн.10)

>>> (Правый сдвиг с заполнением нулями)

Этот оператор сдвигает биты первого операнда вправо. Лишние биты справа отбрасываются. Слева добавляются нулевые биты.

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

Для отрицательных чисел - результат работы разный. Например, -9 >>> 2 даст 1073741821, отличное от -9 >> 2 (дает -3):

Пример:
Выделить все
-9 (по осн.10)
  = 11111111111111111111111111110111 (по осн.2)
                    --------------------------------
-9 >>> 2 (по осн.10)
  = 00111111111111111111111111111101 (по осн.2) 
  = 1073741821 (по осн.10)

См. также