Побітове “і” (&), побітове “або” (|), побітове виключальне “або” (^)
Побітові оператори виконують обчислення на бітовому рівні змінних. Вони допомагають вирішувати широке коло поширених проблем програмування.
Побітовий оператор “і” в C++ (одиничний амперсанд — &) використовується між двома іншими цілими виразами. Побітове “і” керує кожною бітовою позицією довколишнього виразу незалежно, керуючись таким правилом: якщо обидва вхідних біти дорівнюють 1, то результат дорівнює 1, в іншому випадку вихід дорівнює 0. Інший спосіб виразити це:
В Arduino тип int має 16-бітове значення, тому використання & між двома виразами int спричиняє виконання шістнадцяти операцій “і”. У фрагменті коду це виглядає так:
Кожен з 16 бітів в a та b обробляються з використанням побітового “і”, всі 16 бітів результату зберігаються в c. Отримане значення становить 01000100 у двійковій системі, що складає 68 у десятковій системі.
Одним з найпоширеніших застосувань побітового “і” є вибір конкретного біта (або бітів) з цілочисельного значення, яке часто називають маскуванням. Дивіться приклад нижче.
Побітовий оператор “чи” у C++ позначається вертикальною рискою (|). Як і оператор “і”, оператор “чи” керує кожним бітом незалежно в двох навколишніх цілочисельних виразах, але що він робить, звісно ж, відрізняється. Побітове “чи” видає одиницю, якщо обидва або будь-який один з двох бітів видає одиницю, в іншому випадку видає нуль. Іншими словами:
Нижче представлено використання побітового “чи” у фрагменті коду C++:
Поширеним застосуванням побітових операторів “і” та “чи” є, як його називають програмісти, читання-модифікація-запис в порт. На мікроконтролерах портом є 8-бітне число, яке відображає стан пінів. Запис в порт контролює всі контакти відразу.
PORTD — це вбудована константа, яка відсилає до вихідних значень пінів 0,1,2,3,4,5,6,7. Якщо є одиниця в позиції біта, то значення піна HIGH. (Піни вже мають бути налаштовані як виходи командою pinMode()). Отже, якщо ми напишемо PORTD = B00110001, у пінів 0, 4 та 5 буде значення HIGH. Одна невелика заковика полягає в тому, що ми також могли змінити стан пінів 0 та 1, які використовуються Arduino для послідовного зв’язку, тому ми могли йому завадити.
Алгоритм програми такий:
Є один незвичний оператор у C++ під назвою побітове виключне або заперечне “чи”, який позначається ^. Цей оператор дуже схожий до побітового оператора “чи”, тільки він визначає задану бітову позицію як 0, якщо обидва вхідні біти для цієї позиції становлять 1.
Інший спосіб розглянути заперечне “чи”: кожен біт в результаті дає одиницю, якщо вхідні біти різні, або 0, якщо однакові.
Ось простий приклад коду:
Оператор ^ часто використовується для перемикання (тобто переходу від 0 до 1 або від 1 до 0) деяких бітів в цілому виразі. В побітовій операції “або”, якщо є 1 у біті маски, то біт інвертується. Якщо є 0, біт не інвертується і залишається таким самим. Програма нижче змушує мигати цифровий пін 5.
Повернутись до головної
Побітове “і” (&)
Побітовий оператор “і” в C++ (одиничний амперсанд — &) використовується між двома іншими цілими виразами. Побітове “і” керує кожною бітовою позицією довколишнього виразу незалежно, керуючись таким правилом: якщо обидва вхідних біти дорівнюють 1, то результат дорівнює 1, в іншому випадку вихід дорівнює 0. Інший спосіб виразити це:
0 0 1 1 operand1
0 1 0 1 operand2
----------
0 0 0 1 (operand1 & operand2) - результатВ Arduino тип int має 16-бітове значення, тому використання & між двома виразами int спричиняє виконання шістнадцяти операцій “і”. У фрагменті коду це виглядає так:
int a = 92; // у двійковій системі: 0000000001011100
int b = 101; // у двійковій системі: 0000000001100101
int c = a & b; // результат: 0000000001000100, або 68 у десятковій системіКожен з 16 бітів в a та b обробляються з використанням побітового “і”, всі 16 бітів результату зберігаються в c. Отримане значення становить 01000100 у двійковій системі, що складає 68 у десятковій системі.
Одним з найпоширеніших застосувань побітового “і” є вибір конкретного біта (або бітів) з цілочисельного значення, яке часто називають маскуванням. Дивіться приклад нижче.
Побітове “чи” (|)
Побітовий оператор “чи” у C++ позначається вертикальною рискою (|). Як і оператор “і”, оператор “чи” керує кожним бітом незалежно в двох навколишніх цілочисельних виразах, але що він робить, звісно ж, відрізняється. Побітове “чи” видає одиницю, якщо обидва або будь-який один з двох бітів видає одиницю, в іншому випадку видає нуль. Іншими словами:
0 0 1 1 operand1
0 1 0 1 operand2
----------
0 1 1 1 (operand1 | operand2) - результатНижче представлено використання побітового “чи” у фрагменті коду C++:
int a = 92; // у двійковій системі: 0000000001011100
int b = 101; // у двійковій системі: 0000000001100101
int c = a | b; // результат: 0000000001111101, або 125 у десятковій системі.Приклад для Arduino Uno
Поширеним застосуванням побітових операторів “і” та “чи” є, як його називають програмісти, читання-модифікація-запис в порт. На мікроконтролерах портом є 8-бітне число, яке відображає стан пінів. Запис в порт контролює всі контакти відразу.
PORTD — це вбудована константа, яка відсилає до вихідних значень пінів 0,1,2,3,4,5,6,7. Якщо є одиниця в позиції біта, то значення піна HIGH. (Піни вже мають бути налаштовані як виходи командою pinMode()). Отже, якщо ми напишемо PORTD = B00110001, у пінів 0, 4 та 5 буде значення HIGH. Одна невелика заковика полягає в тому, що ми також могли змінити стан пінів 0 та 1, які використовуються Arduino для послідовного зв’язку, тому ми могли йому завадити.
Алгоритм програми такий:
- Отримати 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; // сполучити інформацію з порту з новою інформацією для LED пінів
Serial.println(PORTD, BIN); // налагодження, щоб показати маскування
delay(100);
}
}Побітове заперечне “чи” (^)
Є один незвичний оператор у C++ під назвою побітове виключне або заперечне “чи”, який позначається ^. Цей оператор дуже схожий до побітового оператора “чи”, тільки він визначає задану бітову позицію як 0, якщо обидва вхідні біти для цієї позиції становлять 1.
0 0 1 1 operand1
0 1 0 1 operand2
----------
0 1 1 0 (operand1 ^ operand2) - результатІнший спосіб розглянути заперечне “чи”: кожен біт в результаті дає одиницю, якщо вхідні біти різні, або 0, якщо однакові.
Ось простий приклад коду:
int x = 12; // у двійковій системі: 1100
int y = 10; // у двійковій системі: 1010
int z = x ^ y; // у двійковій системі: 0110, або 6 у десятковійОператор ^ часто використовується для перемикання (тобто переходу від 0 до 1 або від 1 до 0) деяких бітів в цілому виразі. В побітовій операції “або”, якщо є 1 у біті маски, то біт інвертується. Якщо є 0, біт не інвертується і залишається таким самим. Програма нижче змушує мигати цифровий пін 5.
// Blink_Pin_5
// зразок для побітового заперечного “чи”
void setup(){
DDRD = DDRD | B00100000; // налаштувати цифровий пін 5 як вихід
Serial.begin(9600);
}
void loop(){
PORTD = PORTD ^ B00100000; // інвертувати біт 5 (цифровий пін 5), інші залишити непорушними
delay(100);
}Повернутись до головної

Коментарі 0