Побитовое И (&), Побитовое ИЛИ (|), Сложение по модулю два (^)

Описание

Битовые операторы выполняют свои расчеты на уровне битов переменных. Они помогают решать широкий круг общих проблем программирования. Хорошую статью по битовым операциям можно найти на Википедии


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

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


Иллюстрация:

0  0  1  1    операнд1
0  1  0  1    операнд2
----------
0  0  0  1    результат (операнд1 & операнд2)


В среде разработки Arduino тип int это 16-битное значение, таким образом оператор побитовое И между двумя int выражениями делает 16 одновременных И операций.

Иллюстрация:

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

Каждый бит значений a и b проходит операцию побитового И, в результате все 16 битов попадают в переменную c, полученное значение будет 01000100, что равносильно 65 в двоичном представлении.

Наиболее часто операция побитового И используется для выбора конкретного бит (или битов) от целого значения, часто называемая маска. См. пример ниже.


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

Побитовое ИЛИ в C++ обозначается вертикальной чертой, |. Как и оператор &, оператор | работает независимо с каждым битом окружающиъ его чисел. Результат операции побитового ИЛИ двух бит будет 1, если хотя бы один из этих битов 1, иначе резульат будет 0.

Другими словами:

0  0  1  1    операнд1
0  1  0  1    операнд2
----------
0  1  1  1    (операнд1 | операнд2) - результат


Пример использования операции побитового ИЛИ в фрагменте кода на C++:

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


Пример программы

Основная область применения операторов побитовое И/ИЛИ это операции чтение/записи в порт. В микроконтроллерах порт это 8-битовое число, через которое можно получить информацию о состоянии контактов. Записи в порт контролирует все контакты сразу.

PORTD является встроенной константой, которая относится к выходному состоянию цифровых выводов 0,1,2,3,4,5,6,7. Если в каком-то бите установлена 1, значит на выводе состояние HIGH. (Вывод при этом должен быть установлен как выход командой pinMode().) Таким образом, если записать PORTD = B00110001; мы установим выводы 2,3 и 7 в состояние логической 1.

Наш алгоритм будет выглядеть вот так:

  • Получить значение PORTD и очистить биты относящиеся к выводам, значение которые мы хотим изменить (с помощью побитового И).
  • Скомбинировать значение PORTD с нашим новым значением (через операцию побитового ИЛИ).
int i;     // переменная счетчика
int j;
 
void setup()
{
  DDRD = DDRD | B11111100; // установить биты направлений для выводов с 2 по 7, оставить нетронутыми для выводов 0 и 1 (xx | 00 == xx)
  // это тоже самое что и оператор pinMode(pin, OUTPUT) для выводов с 2 по 7
  Serial.begin(9600);
}
 
void loop()
{
  for (i=0; i<64; i++)
  {
    PORTD = PORTD & B00000011;  // очистить биты с 2 по 7, оставить биты (а занчить и выводы) 0 и 1 неизмененными (xx & 11 == xx)
    j = (i << 2);               // сдвинуть переменную на два бита влево к пинам 2 -7, чтобы не затронуть пины 0 и 1
    PORTD = PORTD | j;          // скомбинирвать значение порта с новым значением
    Serial.println(PORTD, BIN); // для отладки выведем значение порта в терминал
    delay(100);
  }
}


Побитовое XOR или исключающее ИЛИ (^)

Еще один побитовый оператор, немного похожий на обычное бинарное ИЛИ, но небольшим отличием - он вернет 0, если оба бита будут равны 1. Обозначается символом ^.

0  0  1  1    операнд1
0  1  0  1    операнд2
----------
0  1  1  0    (операнд1 ^ операнд2) - результат

Другими словами, после операции исключающего ИЛИ будет 1 в том случае, если входные биты различны или оба равны 0.


Пример кода

int x = 12;     // в бинарном представлении: 1100
int y = 10;     // в бинарном представлении: 1010
int z = x ^ y;  // в бинарном представлении: 0110, или десятчиная 6
Оператор ^ часто используется для переключения (т.е. чтобы изменить 0 на 1 или 1 на 0) каких-либо битов в цифровом представлении. Пример программы для переключения цифрового вывода 5.

void setup()
{
  DDRD = DDRD | B00100000; // установили цифровой вывод 5 как выход
  Serial.begin(9600);
}

void loop()
{
  PORTD = PORTD ^ B00100000;  // переключили бит 5 (цифровой вывод 5), остальные оставили нетронутыми
  delay(100);
}


Смотрите также

Расскажи о нас

Сообщение

Если у Вас есть опыт в работе с Arduino и собственно есть время для творчества, мы приглашаем всех желающих стать авторами статей публикуемых на нашем портале. Это могут быть как уроки, так и рассказы о ваших экспериментах с Arduino. Описание различных датчиков и модулей. Советы и наставления начинающим. Пишите и размещайте свои статьи в соответсвующей ветке форума.

Последние комментарии