Operatory bitowe



Operatory bitowe w Arduino

Uwaga: Osoby początkujące mogą pominąć ten rozdział i wrócić do niego później. Zawiera on bardziej zaawansowane zagadnienia, które nie są konieczne na początku nauki Arduino, ale pozwalają lepiej zrozumieć jego pełne możliwości. Umieszczono go tutaj dla zachowania spójności materiału i przedstawienia pełnego zakresu funkcji Arduino.

Operatory bitowe w Arduino pozwalają na manipulację poszczególnymi bitami w liczbach. Są one szczególnie użyteczne w operacjach na rejestrach, maskowaniu wartości oraz optymalizacji kodu dla mikrokontrolerów. Dzięki nim można efektywnie zarządzać stanami wyjść cyfrowych, przetwarzać sygnały oraz sterować sprzętem na poziomie bitów.

W poniższej tabeli (Tab.1) przedstawiono listę operatorów bitowych dostępnych w Arduino:

Tab. 1. Operatory bitowe w Arduino.
Operator Opis
& Operator „AND” bitowy – zwraca 1 tylko wtedy, gdy oba odpowiadające sobie bity są równe 1.
| Operator „OR” bitowy – zwraca 1, jeśli przynajmniej jeden z odpowiadających sobie bitów jest równy 1.
^ Operator „XOR” bitowy – zwraca 1, jeśli dokładnie jeden z odpowiadających sobie bitów jest równy 1.
~ Operator „NOT” bitowy – neguje każdy bit liczby (zamienia 1 na 0 i odwrotnie).
<< Operator przesunięcia w lewo – przesuwa bity wartości w lewo o określoną liczbę miejsc, co jest równoznaczne z mnożeniem przez 2.
>> Operator przesunięcia w prawo – przesuwa bity wartości w prawo o określoną liczbę miejsc, co jest równoznaczne z dzieleniem przez 2.

Dlaczego używamy 0b do zapisu liczb binarnych?

W języku C/C++ oraz w Arduino przedrostek 0b oznacza, że liczba jest zapisana w systemie binarnym. Dzięki temu można w czytelny sposób określać konkretne bity, co jest szczególnie przydatne w operacjach bitowych i pracy z rejestrami mikrokontrolera.

Przykład użycia (Kod_001):

Kod_001

Bez przedrostka 0b kompilator nie rozpozna liczby jako binarnej. Liczby rozpoczynające się od 0, ale bez b, są traktowane jako ósemkowe (system liczbowy o podstawie 8). Na przykład (Kod_002):

Kod_002

W systemie ósemkowym można używać tylko cyfr 0-7, więc zapis 00001111 oznacza liczbę ósemkową 11118, co w systemie dziesiętnym odpowiada 585. Może to prowadzić do błędów i nieoczekiwanych wyników.




Dlaczego używamy skrótu “BIN” w funkcji Serial.println()?

W funkcji Serial.println() można podać drugi argument, który określa system liczbowy, w jakim chcemy wyświetlić liczbę. Dostępne formaty to:

  • DEC – dziesiętny (domyślny)
  • HEX – szesnastkowy
  • OCT – ósemkowy
  • BIN – binarny

Poniżej przedstawiono przykład użycia drugiego argumentu w funkcji Serial.println()Symulacja_1.

Symulacja_1

Dzięki użyciu BIN, liczba zostanie wyświetlona w formie binarnej zamiast formy dziesiętnej, co jest przydatne przy analizowaniu wartości bitowych.

Uwaga: Arduino nie wyświetla zer wiodących (początkowych zer) w funkcji Serial.println();, ponieważ traktuje liczbę binarną jak zwykłą liczbę całkowitą, a początkowe zera nie zmieniają jej wartości. Na przykład Serial.println(0b00000001, BIN); wyświetli “1”, a Serial.println(0b00001000, BIN); wyświetli “1000” zamiast pełnych 8 bitów.




Operator & (AND) – maskowanie bitów

Operator & wykonuje operację AND na poziomie bitów. Pozwala na sprawdzanie wybranych bitów liczby bez wpływu na pozostałe (Symulacja_2).

Przykład: Wydobycie konkretnego bitu

Symulacja_2

Wynik to 00000010 (czyli 2 w systemie dziesiętnym) – tylko drugi bit od prawej został zachowany, ponieważ AND zwraca 1 tylko wtedy, gdy oba odpowiadające sobie bity są równe 1.




Operator | (OR) – ustawianie bitów

Operator | pozwala na ustawienie wybranego bitu bez zmiany pozostałych.

Przykład: Włączenie konkretnego bitu (Symulacja_3).

Symulacja_3

Wynik to 00000100 (czyli 4 w systemie dziesiętnym) – trzeci bit od prawej został ustawiony na 1, reszta bitów pozostała bez zmian.




Operator ^ (XOR) – zmiana stanu bitu

Operator ^ służy do zmiany (przełączania) wybranego bitu (Symulacja_4).

Symulacja_4

Wynik to 00000000 (czyli 0 w systemie dziesiętnym) – trzeci bit został przełączony z 1 na 0.




Operator ~ (NOT) – negacja bitów

Operator ~ odwraca wszystkie bity liczby (Symulacja_5).

Symulacja_5

Wynik to 11110000 (czyli 240 w systemie dziesiętnym) – każdy 1 został zamieniony na 0, a każdy 0 na 1.




Operator << (Przesunięcie w lewo)

Operator << przesuwa wszystkie bity liczby w lewo o określoną liczbę miejsc. Każde przesunięcie o 1 miejsce w lewo powoduje podwojenie wartości liczby (Symulacja_6).

Symulacja_6

Wynik:
Przed przesunięciem: 00000001 (1 w systemie dziesiętnym)
Po przesunięciu: 00001000 (8 w systemie dziesiętnym)

Każde przesunięcie w lewo o 1 miejsce mnoży wartość przez 2. W tym przypadku 1 << 3 oznacza 1 × 23 = 8.




Operator >> (Przesunięcie w prawo)

Operator >> przesuwa wszystkie bity liczby w prawo o określoną liczbę miejsc. Każde przesunięcie o 1 miejsce w prawo powoduje podzielenie wartości przez 2 (Symulacja_7).

Symulacja_7

Wynik:
Przed przesunięciem: 10000000 (128 w systemie dziesiętnym)
Po przesunięciu: 00010000 (16 w systemie dziesiętnym)

Każde przesunięcie w prawo o 1 miejsce dzieli wartość przez 2. W tym przypadku 128 >> 3 oznacza 128 ÷ 23 = 16.




Przykład: Sprawdzanie parzystości liczby za pomocą operatora bitowego AND

Operatory bitowe pozwalają na szybkie i efektywne operacje na liczbach binarnych. Jednym z praktycznych zastosowań jest sprawdzenie, czy liczba jest parzysta czy nieparzysta.

W systemie binarnym:

  • Liczby parzyste mają ostatni bit równy 0 (np. 00000010 = 2, 00000100 = 4).
  • Liczby nieparzyste mają ostatni bit równy 1 (np. 00000011 = 3, 00000101 = 5).

Operator bitowy & (AND) pozwala na sprawdzenie ostatniego bitu:

  • liczba & 1 zwróci 0 dla liczb parzystych.
  • liczba & 1 zwróci 1 dla liczb nieparzystych.

Przykład sprawdzenia parzystości liczby – Symulacja_8:

Symulacja_8

W powyższym przykładzie liczba = 37 (w systemie binarnym to 00100101),
00100101 & 00000001 daje wynik 00000001, więc liczba jest nieparzysta.
Dla liczby 36 (00100100), 00100100 & 00000001 da wynik 00000000, więc liczba jest parzysta.

Sprawdzanie parzystości za pomocą operatora & (liczba & 1) jest bardziej wydajne niż tradycyjna metoda liczba%2 == 0, ponieważ operacja bitowa wykonuje się szybciej niż dzielenie, co ma znaczenie w systemach wbudowanych i optymalizacji kodu.




Kolejność wykonywania operatorów bitowych w Arduino

Podczas wykonywania operacji bitowych obowiązuje hierarchia operatorów, określająca kolejność ich przetwarzania. Od najwyższego do najniższego priorytetu:

  1. Negacja bitowa (~) – odwraca wszystkie bity liczby.
  2. Przesunięcia bitowe (<<, >>) – przesuwają bity w lewo lub w prawo.
  3. AND bitowy (&) – zwraca 1, jeśli oba odpowiadające sobie bity są 1.
  4. XOR bitowy (^) – zwraca 1, jeśli dokładnie jeden z odpowiadających sobie bitów jest 1.
  5. OR bitowy (|) – zwraca 1, jeśli przynajmniej jeden z odpowiadających sobie bitów jest 1.

Aby zmienić kolejność wykonywania operacji, można stosować nawiasy (), które mają najwyższy priorytet.




Asystent Arduinowo_AI

Asystent Arduinowo_AI zgłębił powyższy zakres wiedzy i z przyjemnością wszystko Ci wyjaśni.




Weź udział w quizie i sprawdź, ile wiedzy z modułu A udało Ci się opanować!




Zdobądź więcej wiedzy!

Przejdź do kolejnych materiałów naszego kursu: IF…ELSE – Instrukcje warunkowe.