O co chodzi z przesunięciem bitowym w lewo lub w prawo?

0

Witam,

o co chodzi z przesunięciem bitowym w lewo (<<) lub w prawo (>>)? Do czego potrzebna jest taka konstrukcja? Kiedy początkujący ma okazję wykorzystać tę konstrukcję?

2

Zależy co piszesz

Ogólnie przydaje się do flag. Przeważnie użycie można znaleźć w embedded. Czasami w grach

Dla początkujących raczej nie przydatne jeżeli nie idziesz w embedded

6

Bardzo sytuacyjne. Przez pierwsze parę lat programowania praktycznie ich nie używałem (trochę jak operatory & i | - ale tutaj przynajmniej jest oczywiste zastosowanie do flag).

Ale z kolei od jakiegoś czasu robię dość sporo rzeczy niskopoziomowych i okazuje się że jednak mają sporo zastosowań. Szczególnie w kryptografii ciężko sobie wyobrazić implementowanie niektórych rzeczy bez przesunięć bitowych.

TL;DR jeśli nie wiesz do czegoich potrzebujesz to znaczy że nie potrzebujesz ;). W szczególności zerwij od razu kontakty z ludźmi którzy namawiają Cię do zamieniania a*2 na a << 1 "dla wydajności". Nie potrzebujesz tego typu rad w swoim życiu.

0

Dobrze a czym są te "flagi"?

7

Flaga to nic innego jak stan danego bitu w liczbie – zapalony lub zgaszony. W ten sposób np. do liczby jednobajtowej da się upchnąć osiem wartości logicznych, zamiast jednej. Poniżej przykład takiej liczby:

   00101100
//      ^

Dzióbkiem w komentarzu oznaczyłem interesujący nas bit. Teraz aby sprawdzić stan tego bitu, można skorzystać z trzech technik. Pierwszą z nich jest prosta koniunkcja z maską, w której zapalony jest jedynie interesujący nas bit:

    00101100 // liczba
 &  00000100 // maska
-----------------------
    00000100 // wynik

Jeśli interesujący nas bit jest zapalony, to wynikiem koniunkcji jest liczba różna od zera (zależnie od numeru bitu), w przeciwnym razie wynikiem jest 0. Drugą techniką jest przesunięcie bitowe maski o wartości 1 w lewo, a następnie przeprowadzenie koniunkcji maski wynikowej z liczbą:

     00000001 // maska źródłowa
 <<         2 // indeks bitu
--------------------------------
     00000100 // maska docelowa
 &   00101100 // liczba
--------------------------------
     00000100 // wynik

Wynikiem też będzie 0 lub wartość od niego różna. Trzecią techniką jest wykonanie przesunięcia bitowego liczby w prawo, a następnie przeprowadzenie koniunkcji z maską o wartości 1:

     00101100 // liczba źródłowa
 >>         2 // indeks bitu
---------------------------------
     00001011 // liczba docelowa
 &   00000001 // maska
---------------------------------
     00000001 // wynik

Jeśli nasz bit jest zapalony, to wynikiem powyższych operacji będzie liczba 1, w przeciwnym razie 0.


Tak więc są dwie możliwości – albo sama koniunkcja, albo przesunięcie z koniunkcją. Jeśli sama koniunkcja, to trzeba mieć przygotowaną maskę, a jeśli koniunkcja i przesunięcie to wystarczy liczba źródłowa i numer bitu (który wykorzystujemy jako rozmiar przesunięcia).

Wybrać należy sposób odpowiedni dla danego zastosowania – jeden daje 0 lub 1, a drugi 0 lub liczbę różną od 0.


Tak jak poprzednicy wspomnieli, przesunięcia bitowe używane są przede wszystkim w implementacjach niskopoziomowych. Co prawda można je wykorzystywać do optymalizowania kodu (np. zastępując mnożenie i dzielenie przez potęgi dwójki), jednak tym zajmuje się kompilator, więc nie ma sensu gmatwać kodu takimi zabiegami. Ważne aby wiedzieć jak to działa (kiedyś może się przydać).

Niektóre języki (jak C, C++ czy Free Pascal) wspierają pola bitowe dla struktur, co można wykorzystać do testowania i modyfikacji pojedynczych bitów lub ich zestawów w liczbach. Ale to już na inny temat.

1 użytkowników online, w tym zalogowanych: 0, gości: 1