Pokud chcete používat logické operátory, musíte vědět něco o tom, jak jsou data
uložena v paměti a taky něco o soustavách. Většina z vás to asi zná, vezmu
to rychle. Každé číslo (i znak - znak je vlastně jen 8-mi bitové číslo) je uloženo
jako jeden (více) bajtů - viz. sizeof(). Každý bajt se skládá z bitů, těch je
dnes v jednom bajtu 8. Proto 2 na 8. = 256 (to je ten znak). K těmto jednotlivým
bitům se můžeme rychle dostat právě pomocí lobických operátorů. Bylo by dobré vědět,
co vlastně jednotlivé bity znamenají. Binární (dvojková), taky šestnáctková
(hexadecimální) nebo osmičková (oktálová) a desítková soustava jsou tzv. polynomické
soustavy (snad je to slovo správně, nevím jestli to neznamená cosi jinýho :-)).
Příkladem nepolynomické je třeba římská soustava číslic. (to čím čísluju i tenhle
seriál a co mám zaručeně špatně protže nevím jak spočítat hodnotu) Ale u polytoto
soustav jde hodnota spočítat jednoduše. Soustava má tzv. základ (dvojková má 2,
desítková 10 ...) Potom jde jakékoliv číslo v takové soustavě vyjádřit pomocí vzorce :
To vás asi trochu mate. Prozradíme si že a je ten základ a b je cifra. Cifra má hodnoty od nuly do a - 1. A pokud je nedostatek číslic, použijou se písmeny (hex) No a ten index (u b, mocnina u a) je pořadí oné cifry. Dáme příklad :
Tak. Máme hned tři příklady ! První je v desítkové (to se píše do té závorky) Je to číslo 123 (slovy stodvacettři). To se vyjádří jako 1 krát deset na druhou (jednička je na druhém místě) plus 2 krát deset na prvou plus 3 krát deset na nultou. Když to někam hodíte (do kalkulačky či sálového počítadla), vypadne vám výsledek - 123. (dříve či později :-)) Pomocí takové metody se dají vyjádřit i desetinná čísla, i když to se v binární nebo mexadecimální soustavě nepoužívá. Druhý příklad je hex. Je to to samé, jen je potřeba upozornit že když tam bude písmenko, není to chyba. Dáme tabulku :
Tabulka hexadecimálních čísel
Dekadicky Binárně Hexadecimálně
0 0000 0
1 0001 1
2 0010 2
3 0011 3
4 0100 4
5 0101 5
6 0110 6
7 0111 7
8 1000 8
9 1001 9
10 1010 A
11 1011 B
12 1100 C
13 1101 D
14 1110 E
15 1111 F
To jsou hexadecimální čísla, vyjádřená ještě binárně a dekadicky. Možná vám došla hezká spojitost mezi hex a binární soustavou - dá se mezi nimi hezky převádět, protože číslo v hex zabírá vždy čtyři čísla v binární soustavě. Takže stačí zapamatovat tabulku a máme to jelito kopyto :-) Teď už zpátky k Céčku. Logický součin AND Bit ve výsledku bude jedničkový, pokud budou oba bity v operandech jedničkové. (taky se tomu říká logický součin - násobení)

char a, b, c;
a = 1;    // Bin. 00000001
b = 0x0B; // Bin. 00001011
c = a & b; // And se píše jedno &, neplést s &&
// V c bude 1 (= 00000001)
Tak třeba tohle konkrétně bylo to samé co modulo dvěma. (zbytek po dělení). Většinou se to taky tak používá. O věech těchhle operacích totiž platí že jsou neskonale rychlejší než ostatní. Logický součet OR Bit ve výsledku bude jedničkový, pokud bude aspoň jeden z bitů v operandech jedničkový.

char a, b, c;
a = 3; // Bin. 00000011
b = 5; // Bin. 00000101
c = a | b; // Or se píše jedno |, neplést s ||
V c bude 7. (= 00000111)
To se dá použít pro extrémně rychlé sčítání, pokud víte že složky se "nepřekryjí" (protože pak se to nebude chovat jako součet) To je třeba u různých konstant a třeba u míchání barev z RGB. Ukážu vám že nelžu : 1 0001 +8 Or 1000 9 1001 Opravdu - součet a OR jsou stejné. Ale v případě trojky a pětky to neplatilo.. Exkluzivní binární součet XOR Pokud jsou bajty v operandech rozdílné, bude výsledek 1. Pokud jsou stejné tak 0.

char a, b, c;
a = 3; // Bin. 00000011
b = 5; // Bin. 00000101
c = a ^ b; // Xor se píše ^
// V c bude 6. (= 00000110)
Například rychlé porovnávání : if(a ^ b) je to samé jako if(a != b) Nebo taky pro šifrování nebo rychlé nulování registrů v assembleru. (číslo xor stejné číslo dá vždy nulu - a xor je rychlejší, než tu nulu zkopírovat ;-)) Bitový posun doleva Bity v čísle se posunou doleva o druhé číslo. z prava se jako nové bity přidávají nuly. (pak je ještě rotování, ale jen v assembleru)

char a;
a = 5; // Bin. 00000101
a = a >> 2; // Posuny jsou šipečky, šlo by a >>= 2;
V a bude 1. // 00000001
Toto je vlastně podle toho co jsme si řekli o soustavách také rychlé dělení mocninou dvou a k tomu se to taky používá (jen celočís.) Např.:

a >>= 4; // 2^4 = 16 -> dělení 16-ti
Bitový posun doprava Bity v čísle se posunou doprava o druhé číslo. Z leva se jako nové bity přidávají nuly.

char a;
a = 5; // Bin. 00000101
a = a << 2; // Posuny jsou šipečky, šlo by a <<= 2;
V a bude 20 // 00010100
Toto je také rychlé násobení mocninou dvou (jen celočís.) Např.:

a <<= 3; // 2^3 = 8 -> násobení 8-mi
Negace bit po bitu NOT To se prostě každý bit obrátí z jedničky na nulu nebo z nuly na jedničku. Rozdíl mezi negací a negací bit po bitu je ten, že negace udělá z nenulového čísla nulu nebo z nuly jedničku. Negace bit po bitu prostě obrátí celé číslo (z nuly 0x0000 udělá 0xffff, z jedničky 0x001 udělá 0xfffe a tak dál...)

a = 1;
a = ~a; // taky a ~= a;
Pozor ! Bitové operace mají velmi nízkou prioritu, musí se závorkovat ! Někdo by se mohl ptát, na co to je - využití je hodně xor na šifrování (pokud ho zavoláte podruhé, číslo se vlastně vrátí zpět ;-)) Or je na různé flagy :

#define PAPRIKA 1
#define SYR 2
#define SUNKA 4
// 1 2 4 8 16 32 64 128 256 ...

int flaga;

flaga = 0;

flaga |= PAPRIKA;
flaga |= SYR;

char str[256];

strcpy(str, "Uzivatel si objednal pizzu s ");

if(flaga & PAPRIKA)
    strcat(str, "paprikou, ");
if(flaga & SYR)
    strcat(str, "syrem, ");
if(flaga & SUNKA)
    strcat(str, "sunkou, ");

strcat(str, "a pitivem.\n");

printf("%s", str);
Vytiskne : Uzivatel si objednal pizzu s paprikou, syrem, a pitivem." Protože jsou tak rychlé, používají se ještě třeba u 3D-karet. Je to důvod proč má textura velikost mocniny dvou. (pak se nenásobí, ale posouvají bity) A je tu ještě jeden trik - fixed point čísla. To jsou reálná čísla, se kterými se pracuje jako s integery (rychlejiii !!). Vezmete 32bit. integer a řeknete že prvních šestnáct bitů bude celá část a druhých šestnáct bitů desetinná. Číslo z float na 16:16 fixed point převedete jednoduše násobením 65536 a zaokrouhlením. (násobení 65536 je to samé jako bitový posun doprava) A pak s ním můžete počítat stejně jako s integerem. A když chcete zase vaše reálné číslo, buď to vydělíte 65536 a nebo to zaokrouhlíte posunutím o šestnáct bitů doleva. Fixed point sice není tak přesný jako integer, ale je neskonale rychlejší. Cvičení : 1) - Napište program pro rotaci bitů (ne posun !) a vytiskněte výsledky. 2) - Napište program pro převod čísel mezi soustavama. Bude se vám hodit (i když kalkulačka pod win i ta na stole to umí taky :-)) 3) - Napište program, vypisující mocniny reálných čísel za použití 16:16 fixed point. 4) - Napište program, který zašifruje zadané slovo podle zadaného hesla pomocí xor. (výsledky vypište jako hexa číslice a pak jako text) Hálelujá ! -tHE SWINe-
Zpátky