Bitové logické operácie - k čomu je to dobré
Úloha
-
Podľa postupu si overte ako fungujú základné logické operácie v jazyku C
Teória
Jazyk C dovoľuje jednoduchým spôsobom používať všetky bitové logické operácie ako ich poznáte
z predmetu elektronika. Nakoľko ich potrebujeme odlíšiť od bežných operácií ako je spočítanie a násobenie,
tak sa v jazyku C zapisujú pomocou trochu zvláštnych znakov.
Negácia
Negácia je najjednoduchšia bitová operácia. Vykoná sa tak že stav bitu sa zmení na opačný. Je to takzvaná unárna operácia. To znamená že má
iba jeden operand nad ktorým sa vykonáva. Pravdivostná tabuľka vyzerá takto:
V jazyku C sa táto operácia zapisuje pomocou znaku ~. Niekoľko príkladov ako sa dá použiť negácia v jazyku C
| Operácia |
Zápis |
Príklad |
Výpočet |
Komentár |
| bitová negácia |
~ |
PORTD = ~0; |
|
Operácia priradí PORTD negovanú hodnotu čísla 0. To znamená že tam budú všade jednotky. Ak by sme cheli povedať aká tam bude hodnota
tak je to 255 desiatkovo, alebo 0xFF hexadecimálne.
|
| bitová negácia |
~ |
PORTD = ~0x7B; |
| 0x7B |
0 | 1 | 1 | 1 | 1 | 0 | 1 | 1 |
| ~0x7B |
1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
|
Rovnaký príklad ako predošlý len sa neguje hodnota 0x7B, čo vo výsledku je 0x84
|
| bitová negácia |
~ |
unsigned char znak = 10; PORTD = ~znak; |
| znak |
0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 |
| ~znak |
1 | 1 | 1 | 1 | 0 | 1 | 0 | 1 |
|
Negovať môžeme akýkoľvek výraz. V tomto prípade to je obsah premennej znak.
|
Logický bitový súčet
Ďalšou jednoduchou bitovou operáciou je logický bitový súčet (OR). Operácia sa robí s dvomi operandami. Na rozdiel
od spočítania sa robí logický súčet s jednotlivými bitmi. Pravdivostná tabuľka pre operáciu logický súčet:
| A |
B |
Y = A ∨ B |
| 0 |
0 |
0 |
| 0 |
1 |
1 |
| 1 |
0 |
1 |
| 1 |
1 |
1 |
V jazyku C sa logický bitový súčet zapisuje pomocou znaku |. Opäť niekoľko príkladov na použitie:
| Operácia |
Zápis |
Príklad |
Výpočet |
Komentár |
| bitový súčet |
| |
PORTD = 20 | 0x81; |
| 20 |
0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 |
| 0x81 |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| PORTD |
1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 |
|
V tomto príklade sa spočítajú dve hodnoty a výsledok sa vloží do premennej PORTD.
|
| bitový súčet |
| |
PORTD = PORTD | 0x0C; PORTD |= 0x0C; |
| PORTD |
1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 |
| 0x0C |
0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 |
| PORTD |= 0x0C |
1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 |
|
Tieto dva riadky robia to isté. Druhý zápis je len skrátením toho prvého.
Táto špeciálna konštrukcia hovorí že k premennej PORTD sa má logicky pripočítať výsledok výrazu za znakom =.
V tomto prípade to je priamo hodnota 0x0C. Táto hodnota má jednotky na pozícii druhého a tretieho bitu.
Všimnite si že výsledkom operácie je že bity druhý a tretí bit PORTD sa nastaví na jedna bez ohľadu aká tam predtím bola hodnota.
Pričom všetky ostatné bity PORTD zostali nezmené
|
| bitový súčet |
| |
unsigned char znak = 0xB7; #define SEG_H 0x40; PORTD = ~(znak | SEG_H); |
| znak |
1 | 0 | 1 | 1 | 0 | 1 | 1 | 1 |
| SEG_H |
0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
| znak | SEG_H |
1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 |
| ~(znak | SEG_H) |
0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
|
Tento komplexný príklad ukazuje ako do premennej PORTD vložíme výsledok spočítania premennej ktorá obsahuje znak.
K tomu sa pripočíta symbolická textová konštanta ktorá reprezentuje bit na ktorom je pripojený segment desatinnej bodky.
Celý výsledok sa neguje a vloží do premennej PORTD.
|
Logický bitový súčin
Ďalšou jednoduchou bitovou operáciou je logický bitový súčin (AND). Operácia sa robí s dvomi operandami. Na rozdiel
od aritmetického násobenia sa robí logický súčin s jednotlivými bitmi. Pravdivostná tabuľka pre operáciu logický súčet:
| A |
B |
Y = A ∧ B |
| 0 |
0 |
0 |
| 0 |
1 |
0 |
| 1 |
0 |
0 |
| 1 |
1 |
1 |
V jazyku C sa logický bitový súčin zapisuje pomocou znaku &. Opäť niekoľko príkladov na použitie:
| Operácia |
Zápis |
Príklad |
Výpočet |
Komentár |
| bitový súčin |
& |
PORTD = 20 & 0x87; |
| 20 |
0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 |
| 0x81 |
1 | 0 | 0 | 0 | 0 | 1 | 1 | 1 |
| PORTD |
0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
|
V tomto príklade sa logicky vynásobia dve hodnoty a výsledok sa vloží do premennej PORTD.
|
| bitový súčin |
& |
PORTD = PORTD & 0xFE; PORTD &= 0xFE; |
| PORTD |
1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 |
| 0xFE |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
| PORTD &= 0xFE |
1 | 0 | 0 | 1 | 1 | 1 | 0 | 0 |
|
Tieto dva riadky robia to isté. Druhý zápis je len skrátením toho prvého.
Táto špeciálna konštrukcia hovorí že k premennej PORTD sa má logicky vynásobiť výsledok výrazu za znakom =.
V tomto prípade to je priamo hodnota 0xFE. Táto hodnota má nulu na pozícii nultého bitu.
Všimnite si že výsledkom operácie je že nultý bit PORTD sa nastaví na nula bez ohľadu aká tam predtím bola hodnota.
Pričom všetky ostatné bity PORTD zostali nezmené
|
| bitový súčin |
& |
PORTD = 0x74; #define TR1 0x20 #define TR2 0x10 #define TR3 0x08
#define MASKA (TR1 | TR2 | TR3) PORTD |= MASKA;
PORTD &= ~TR1; |
| PORTD; |
0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 |
| TR1 |
0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
| TR2 |
0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
| TR3 |
0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
| MASKA |
0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 |
| PORTD | MASKA |
0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 |
| PORTD & ~TR1) |
0 | 1 | 0 | 1 | 1 | 1 | 0 | 0 |
|
Tento komplexný príklad ukazuje ako sa programovo rieší vypnutie PNP tranzistora TR3 pripojeného na port PD3 a následné
zapnutie tranzistora TR1 pripojeného na PD5. Tranzistor je zapnutý ak je hodnota bitu logická 0. Aktuálny stav je že je zapnutý
TR3. Následne sa TR3 vypne a potom TR1 zapne.
|
Noekvivalenia
Ďalšou bitovou operáciou je operácia noekvivalenia (nerovná sa) (XOR). Operácia sa robí s dvomi operandami.
Pravdivostná tabuľka pre operáciu XOR:
| A |
B |
Y = A ^ B |
| 0 |
0 |
0 |
| 0 |
1 |
1 |
| 1 |
0 |
1 |
| 1 |
1 |
0 |
Jedoducho povedané bit výsledku je jednotkový ak sa vstupné bity nerovnajú.
V jazyku C sa noekvivalencia zapisuje pomocou znaku ^. Opäť niekoľko príkladov na použitie:
| Operácia |
Zápis |
Príklad |
Výpočet |
Komentár |
| noekvivalencia |
^ |
PORTD = 101 ^ 0x0F; |
| 101 |
0 | 1 | 1 | 0 | 0 | 1 | 0 | 1 |
| 0x0F |
0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
| PORTD |
0 | 1 | 1 | 0 | 1 | 0 | 1 | 0 |
|
V tomto príklade sa urobí XOR dvoch čísel výsledok nie je nulový čo znamená že čisla boli rôzne.
Možete si všimnúť že dolné štyri bitu sú vlastne negované.
|
| noekvivalencia |
^ |
PORTD = PORTD ^ 0x6A; PORTD ^= 0x6A; |
| PORTD |
0 | 1 | 1 | 0 | 1 | 0 | 1 | 0 |
| 0x6A |
0 | 1 | 1 | 0 | 1 | 0 | 1 | 0 |
| PORTD ^= 0x6A |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|
Tieto dva riadky robia to isté. Druhý zápis je len skrátením toho prvého.
Teraz výsledok hovorí že PORTD obsahoval hodnoptu 5 pretože výsledok je nula.
|
| noekvivalencia |
| |
PORTD = 0xEE; #define TR1 0x40; PORTD ^= TR1; PORTD ^= TR1; |
| PORTD |
1 | 1 | 1 | 0 | 1 | 1 | 1 | 0 |
| TR1 |
0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
| PORTD ^= TR1 |
1 | 0 | 1 | 0 | 1 | 1 | 1 | 0 |
| PORTD ^= TR1 |
1 | 1 | 1 | 0 | 1 | 1 | 1 | 0 |
|
Operácia xor môže slúžiť aj k negácii určitého vybraného bitu. Tento príklad definuje symbolickú textovú konštantu
TR1. Jej hodnota je 0x40 čo znamená že ide o bit číslo 6.
Operácia XOR bit 6 zneguje pričom všetky ostatné zostanú nezmenené.
Ostatné si zachovajú svoje pôvodné hodnoty.
|
Postup