Jason. Cała informatyka w jednym miejscu!

Coraz mniej czasu w ciągu dnia, więc postanowiłem wziąć na klatę podobny temat zbliżony do poprzedniego (poprzednio pisałem o przesunięciach bitowych). Mają ze sobą wiele wspólnego (przesunięcia to jeden z typów) więc postanowiłem "postawić" te wątki obok siebie. Przed Wami, następna opowieść o alternatywnych zapisach. W roli głównej, operatory bitowe, ale nie te, które już dobrze znacie.

OPERATORY BITOWE. TŁUMACZENIE W PIGUŁCE

Wyjaśnienia dzielą się na proste i szybkie oraz długie i naukowe. Są jeszcze takie, które się w ogóle nie nadają :D. W każdym razie, objaśnię ten temat trzymając się pierwszego wariantu. Tak na poważnie przechodząc do tematu, nie będę się produkował na temat tych klasycznych operatorów jak negacja (!) czy koniunkcja (&&). Raczej skupię się na pojedynczym ampersandzie (&) oraz pojedynczej pionowej kresce (|). Oba te zapisy są obsługiwane przez niektóre języki wysokiego poziomu (na pewno C, C++, Java i C#) i służą do obliczania liczb w systemie binarnym. Takie ładne terminy to "koniunkcja binarna" i "alternatywa binarna". Operatory bitowe posiadają również takie rodzaje. Pozwólcie, że po raz kolejny zaprezentuję przykłady.

KONIUNKCJA BITOWA

Oprócz dobrze znanej koniunkcji "zwykłej" w postaci dwóch ampersandów (&&) istnieje również odmiana zastosowania koniunkcji dla liczb binarnych, która zwraca liczbę binarną w wyniku zastosowania operatora AND dla podanych dwóch / więcej liczb binarnych pod kreską. Tak wygląda przykład:

Zakładając, że mamy liczbę 45 w systemie binarnym:

0 0 1 0 1 1 0 1

 

oraz drugą liczbę binarną jako 78:

0 1 0 0 1 1 1 0

To przy zastosowaniu koniunkcji binarnej wynik będzie równy 12. Dlaczego? Ponieważ porównujemy każdy bit od lewej do prawej i tam, gdzie w obu przypadkach występuje 1, zapisujemy 1 (przypadek, gdy wszystkie warunki są prawdziwe). W przeciwnym razie podajemy zero. Widzicie sami, że operatory bitowe nie kończą się jedynie na kilku podstawowych. Weźmy sobie te obie liczby pod kreską:

0 0 1 0 1 1 0 1
0 1 0 0 1 1 1 0
0 0 0 0 1 1 0 0

W tym momencie nic nie powinno budzić wątpliwości. Po porównaniu sobie wszystkich osobnych bitów pojedynczo łatwo zauważyć, że jedynki są tylko tam, gdzie w obu liczbach też występuje jedynka. Zatem po zamianie na system dziesiętny mamy 12. Dodam, że można wprowadzać wiele liczb niż dwie. Na przykład koniunkcja bitowa z liczb 45, 78 oraz 105 da wynik równy 8. Pokombinujcie sami jak to policzyć. W językach wysokiego poziomu, najczęstszym "znakiem rozpoznawczym" jest pojedynczy ampersand (&).

ALTERNATYWA BITOWA

Alternatywa binarna działa podobnie, tylko że teraz wykonujemy badanie typu OR (prawda, gdy co najmniej jeden z kilku warunków jest prawdziwy), więc zasada identyczna jak przy alternatywie "klasycznej". Mamy ten sam zbiór liczb 45 i 78. Zatem alternatywa bitowa dla tych liczb będzie równa 111. Rozrysujmy to sobie jeszcze raz:

0 0 1 0 1 1 0 1
0 1 0 0 1 1 1 0
0 1 1 0 1 1 1 1

Zgodnie z alternatywą, wystarczy jeden warunek spełniony, aby zdanie było prawdziwe. Wniosek nasuwa się samoistnie. Znak pionowej kreski (|), tak rozpoznacie alternatywę bitową w kodzie (zazwyczaj).

NEGACJA BITOWA

Operatory bitowe "uzbrojone" są także w klasyczną negację. Negacja binarna to, jak łatwo się domyślić, przestawienie bitów na przeciwną wartość. Wszystkie jedynki są zerami, a zera...domyślcie się. To jest operator unarny, czyli wykonujący operacje na pojedynczym argumencie ("operandzie"). I tak biorąc sobie dla przykładu liczbę 83, wynikiem jej zanegowania będzie -84. Żeby zrozumieć skąd się wziął wynik, potrzebna jest wiedza o tak zwanym "bicie znaku". Bit znaku to jest ta cyferka występująca jako pierwsza, licząc od lewej strony. Normalnie bity oznaczają składniki sumy n-tej potęgi liczby 2. W przypadku, gdy bit znaku staje się "jedynką", oznaczać będzie ujemną wartość wynikową, a co za tym idzie, od sumy trzeba odjąć 2N. Ponieważ ZAWSZE jest odejmowany składnik o najwyższej wartości (najbardziej znaczący bit), to zawsze "przeskoczy" sumę składników dodatnich i stąd powstaje wartość ujemna. Zaprezentuję to na takim samym schemacie jak powyżej. Spójrzcie:

0 1 0 1 0 0 1 1
1 0 1 0 1 1 0 0

Jak wspomniałem, pierwszy bit od lewej to jest bit znaku. Liczba 83 jest dodatnia, więc bit znaku jest ustawiony na zero. Kiedy zanegujemy liczbę 83, to w wyniku "przekręcenia" bitów na przeciwną wartość, poza resztą bitów "normalnych", bit znaku także posiada wartość 1. Celem przekonwertowania na system dziesiętny, późniejsze kalkulacje wyglądają w taki sposób:

-27 + 25 + 23 + 22 = -128 + 32 + 16 + 8 = -84

Negacja bitowa jest oznaczana na kilka sposobów, w zależności od języka programowania bo to może być pod postacią operatora albo funkcji. Jednakże najczęstszym symbolem jest znak tyldy (~).


Mamy następny temat załatwiony. Operatory bitowe, ale te mniej znane. Dodam, że języki obsługujące te operacje pozwalają na skrócony zapis (&=, |= itd.), taki sam jak przy wszystkich podstawowych operacjach. Zastosowanie w praktyce oprócz szpanu? Konfigurowanie aplikacji w postaci nakładania "maski bitowej" dla przykładu (tak się bardzo często robi w C++).

PODOBNE ARTYKUŁY