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

^ (bitwise XOR)

Оператор ^ (побитовый XOR) возвращает 1, если биты операндов различаются — удобен для переключения битов и сравнения флагов.

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

Описание

Побитовый XOR — один из наиболее специфичных операторов C++. Он обозначается символом каретки ^ и работает с каждой парой битов двух целых чисел независимо: если биты различаются (один равен 0, другой равен 1), результирующий бит будет 1. Если биты одинаковые — результат 0.

Главное отличие от обычного OR: XOR не даёт 1, когда оба бита равны 1. Отсюда и название — исключающее ИЛИ.

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

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

Пример кода

    int x = 12;     // двоичное: 1100
    int y = 10;     // двоичное: 1010
    int z = x ^ y;  // двоичное: 0110, или десятичное 6

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

Оператор ^ чаще всего используют в двух ситуациях:

  • Переключение (toggle) отдельных битов — удобно для управления несколькими выходами через один регистр или переменную.
  • Простое шифрование — XOR с ключом маскирует данные, а повторное применение того же ключа восстанавливает исходное значение.
  • Сравнение флагов — быстро выяснить, какие именно биты изменились между двумя состояниями.
  • Генерация контрольных сумм — XOR всех байт блока данных даёт простой, но быстрый способ обнаружить одиночную ошибку.

Переключение битов с помощью маски

Самое частое применение ^ в Arduino-скетчах — инвертировать нужные биты, не трогая остальные. Принцип прост: в маске ставим 1 там, где хотим переключить бит, и 0 там, где бит должен остаться без изменений.

    // Примечание: этот код использует регистры, специфичные для микроконтроллеров AVR (Uno, Nano, Leonardo, Mega и др.)
    // он не скомпилируется для других архитектур
    void setup() {
      DDRB = DDRB | 0b00100000;  // установить PB5 (пин 13 на Uno/Nano, пин 9 на Leonardo/Micro, пин 11 на Mega) как OUTPUT
      Serial.begin(9600);
    }

    void loop() {
      PORTB = PORTB ^ 0b00100000;  // инвертировать PB5, остальные не трогать
      delay(100);
    }

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

  • Оператор ^ работает только с целыми типами: int, long, byte, uint8_t и т. д. К числам с плавающей точкой он неприменим.
  • Не путайте ^ с оператором возведения в степень — в C++ такого оператора нет. Для степеней используйте функцию pow().
  • Двойное применение XOR с одной и той же маской возвращает исходное значение: x ^ mask ^ mask == x. Это свойство лежит в основе простого шифрования.
  • При работе с портами микроконтроллера (например, PORTB ^= 0b00000001) XOR позволяет переключить состояние вывода без чтения и записи отдельных битов вручную — код получается компактнее и быстрее.
  • Если результат выглядит неожиданно, выведите значения в Serial Monitor в двоичном виде (Serial.println(value, BIN)) — так сразу видно, какие биты изменились.

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