168
• logiczne “nie”
Oprócz tego są także przesunięcia (« om/. •*). Zastanówmy się teraz, jak je wykorzystać w praktyce. Załóżmy, że zajmujemy się jednobajtową zmienną.
unsigned char i ■ 2;
Z matematyki wiemy, że zapis binarny tej liczby wygląda tak (w ośmiobitowej zmiennej): 00000010. Jeśli teraz np. chcielibyśmy "zapalić" dnigi bit od lewej (tj. bit. którego zapalenie niejako “(kala" do liczby wartość 2®) powinniśmy użyć logicznego lub:
unsigned char i = 2; i I- 64;
Gdzie 64=2°. Odczytywanie wykonuje się za pomocą tzw. maski bitowej. Polega to na:
1. wyzerowaniu bitów, które są nam w danej chwili niepotrzebne
2. odpowiedniemu przesunięciu bitów, dzięki czemu tukany bit znajdzie się na pozycji pierwszego bitu od prawej
Do “wyłuskania” odpowiedniego bitu możemy posłużyć się operacją “i” czyli operatorem &. Wygląda to analogicznie do posługiwania się operatorem "lub":
unsigned char i ■ 3; /* bitowo: 00000011 */ unsigned char temp ■ 0;
temp - i b 1; /• sprawdzamy najmniej znaczący bit - czyli pierwszy z prawej */ if (temp) {
printf ("bit zapalony"); else {
printf ("bit zgaszony");
>
Jeśli nie władasz biegle kodem binarnym, tworzenie masek bitowych ułatwią ci przesunięcia bitowe. Aby uzyskać liczbę która ma za|xtlony bit o numerze n (bity są liczone od zera), przesuwamy bitowo w lewo jedynkę o n pozycji:
1 « n
Jeśli chcemy uzyskać licz!>ę\ w której zapalone są bity na pozycjach 1, m, n używamy sumy logicznej (“lub”):
(1 « 1) I (1 « m) I (1 « n)
Jeśli z kolei chcemy uzyskać liczl>ę gdzie zapalone są wszystkie bity p«»za n. odwracamy ją za pomocą operatora logicznej negacji
"(1 « n)
Warto władać biegle operacjami na bitach, ale początkujący mogą (po uprzednim przeanalizowaniu) zdefiniować następujące makra i ich używać:
/• Sprawdzeni® czy w liczbie k jest zapalony bit n •/
Sdefine IS_BIT_SET(k, n) ((k) * (1 « (n)))
/• Zapalenie bitu n w zmiennej k •/
tdefine SET.BIKk, n) (k I- (1 « (n)))
/• Zgaszenie bitu n w zmiennej k •/
idefine RESET_BIT(k. n) (k A- "(1 « (n)))