Bitové logické operácie - k čomu je to dobré

Úloha

  1. 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:
A
0 1
1 0

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;
0 0000 0000
~0 1111 1111
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 0111 1011
~0x7B 1000 0100
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 0000 1010
~znak 1111 0101
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 0001 0100
0x81 1000 0001
PORTD 1001 0101
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 1001 0101
0x0C 0000 1100
PORTD |= 0x0C 1001 1101
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 1011 0111
SEG_H 0100 0000
znak | SEG_H 1111 0111
~(znak | SEG_H) 0000 1000
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 0001 0100
0x81 1000 0111
PORTD 0000 0100
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 1001 0101
0xFE 1111 1110
PORTD &= 0xFE 1001 1100
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; 0111 0100
TR1 0010 0000
TR2 0001 0000
TR3 0000 1000
MASKA 0011 1000
PORTD | MASKA 0111 1100
PORTD & ~TR1) 0101 1100
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 0110 0101
0x0F 0000 1111
PORTD 0110 1010
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 0110 1010
0x6A 0110 1010
PORTD ^= 0x6A 0000 0000
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 1110 1110
TR1 0100 0000
PORTD ^= TR1 1010 1110
PORTD ^= TR1 1110 1110
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