Все статьи

Побитовые операции: как AND, OR и XOR работают на уровне битов

Битовые операции проще всего понять не через десятичные числа, а через восьмеричную запись прав доступа Unix: команда chmod 640 — это не просто три цифры, а три отдельные тройки битов «чтение-запись-выполнение», собранные в одно число операцией OR. Именно поэтому побитовую логику почти никогда не показывают в десятичной системе — она легко читается только в двоичном или шестнадцатеричном виде.

AND, OR, XOR, NOT — четыре базовые операции

  • AND (&) — результирующий бит равен 1, только если оба входных бита равны 1. В chmod именно AND с маской проверяет, установлен ли конкретный флаг доступа.
  • OR (|) — результирующий бит равен 1, если хотя бы один из входных битов равен 1. Так три отдельных права (r=4, w=2, x=1) складываются в одну цифру, например 4|2|1 = 7.
  • XOR (^) — результирующий бит равен 1, если входные биты различны; применение XOR дважды с тем же значением возвращает оригинал.
  • NOT (~) — инвертирует каждый бит числа.

Чем побитовый AND отличается от логического

Логический AND (&& в большинстве языков) работает с булевыми значениями целиком и даёт true/false, тогда как побитовый AND (&) обрабатывает каждый бит двух чисел отдельно и возвращает число. Путаница между ними — распространённая причина багов.

Почему битовые маски удобнее хранить в двоичном или шестнадцатеричном виде

Число прав доступа 6 в десятичной системе ничего не говорит о том, какие именно флаги установлены, а вот 0b110 сразу читается как «чтение и запись, без выполнения». Ровно поэтому конвертер систем счисления и инструмент побитовых операций используются в связке: прежде чем применять AND/OR/XOR, число почти всегда переводят в двоичный или шестнадцатеричный вид, где структура битов видна напрямую.

Зачем это нужно

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

Ловушка с приоритетом операторов

В большинстве языков программирования побитовые операторы & и | имеют более низкий приоритет, чем операторы сравнения — поэтому выражение вроде if (a & b == c) на самом деле вычисляется как a & (b == c), а не так, как ожидает автор. Это одна из самых распространённых причин трудноуловимых багов при работе с битовыми масками, и надёжный способ избежать её — всегда явно расставлять скобки вокруг побитовых операций.

Попробовать инструмент