Главная chevron_right Структура chevron_right Побитовые операторы chevron_right & (bitwise AND)

& (bitwise AND)

Оператор & сравнивает каждую пару битов двух чисел: результат равен 1 только там, где оба бита равны 1 — удобно для масок и проверки отдельных битов.

Полная статья

Описание

Побитовый AND записывается одиночным амперсандом & и ставится между двумя целочисленными выражениями. Оператор сравнивает каждую пару битов на одинаковых позициях: если оба бита равны 1, результат на этой позиции тоже 1; во всех остальных случаях — 0.

Таблица истинности для одной битовой позиции:

    0  0  1  1    operand1
    0  1  0  1    operand2
    ----------
    0  0  0  1    (operand1 & operand2) - returned result

Важно не путать & с логическим оператором &&: последний работает с булевыми значениями целиком и возвращает true или false, тогда как & работает побитово и возвращает целое число.

На платах с AVR-архитектурой тип int занимает 16 бит, поэтому операция a & b над двумя значениями int одновременно выполняет 16 независимых операций AND — по одной для каждой позиции.

Пример кода

    int a =  92;    // в двоичном виде: 0000000001011100
    int b = 101;    // в двоичном виде: 0000000001100101
    int c = a & b;  // результат:       0000000001000100, или 68 в десятичном виде.

Здесь каждый из 16 бит переменных a и b обрабатывается независимо. Результат сохраняется в c — в двоичном виде это 01000100, что равно 68 в десятичном.

Маскирование битов

Самое частое применение &битовая маска: выделить один или несколько нужных битов из числа, обнулив все остальные. Для этого создаётся «маска» — число, в котором стоят единицы ровно на тех позициях, которые вас интересуют.

Например, чтобы проверить, установлен ли третий бит (считая с нуля) в переменной x, достаточно написать x & 0b00001000. Если результат не равен нулю — бит установлен.

Пример с регистрами (зависит от архитектуры AVR):

    PORTD = PORTD & 0b00000011;  // сбросить биты 2–7, оставить пины PD0 и PD1 нетронутыми (xx & 11 == xx)

Где применяется

  • Чтение состояния отдельного пина через регистры — проверить, установлен ли конкретный бит в порту микроконтроллера, не затрагивая остальные.
  • Разбор байта протокола — выделить поле флагов из байта, полученного по UART, SPI или I2C.
  • Ограничение диапазона значений — быстро «обрезать» число до степени двойки: value & 0xFF оставляет только младшие 8 бит.
  • Проверка чётностиn & 1 равно 0 для чётных чисел и 1 для нечётных.

Практические замечания

  • Не путайте & (побитовый AND) и && (логический AND) — это разные операторы с разным поведением.
  • Размер типа влияет на результат: int на AVR — 16 бит, на ARM (Due, Zero, MKR) — 32 бита. Если важна переносимость, используйте типы фиксированной ширины: int16_t, uint8_t и т. д.
  • При маскировании удобно записывать маску в двоичном виде (0b00001111) или шестнадцатеричном (0x0F) — так сразу видно, какие биты затронуты.
  • Результат & всегда можно вывести в Serial Monitor через Serial.println(c, BIN), чтобы увидеть двоичное представление и убедиться, что маска работает правильно.
  • Операция не изменяет исходные переменные — она возвращает новое значение, которое нужно куда-то сохранить или сразу использовать в условии.

Полезные материалы