Ponieważ nikt nie poruszył tematu, dlaczego są one przydatne:
Często używam operacji bitowych podczas pracy z flagami. Na przykład, jeśli chcesz przekazać serię flag do operacji (powiedzmy File.Open()
, z włączonymi trybami odczytu i zapisu), możesz przekazać je jako jedną wartość. Osiąga się to poprzez przypisanie każdej możliwej flagi jej własnego bitu w zestawie bitów (bajt, krótki, int lub długi). Na przykład:
Read: 00000001
Write: 00000010
Więc jeśli chcesz przekazać odczyt I zapis, powinieneś przekazać (CZYTAJ | ZAPISZ), który następnie łączy te dwa elementy w
00000011
Które następnie można odszyfrować na drugim końcu, na przykład:
if ((flag & Read) != 0) {
który sprawdza
00000011 &
00000001
który powraca
00000001
która nie jest 0, więc flaga określa READ.
Możesz użyć XOR do przełączania różnych bitów. Użyłem tego, gdy używam flagi do określania kierunkowych wejść (w górę, w dół, w lewo, w prawo). Na przykład, jeśli duszek porusza się poziomo i chcę, aby się obracał:
Up: 00000001
Down: 00000010
Left: 00000100
Right: 00001000
Current: 00000100
Po prostu XOR aktualną wartość za pomocą (LEFT | RIGHT), co w tym przypadku wyłącza LEWO i włączam PRAWO.
Przesuwanie bitu jest przydatne w kilku przypadkach.
x << y
jest taki sam jak
x * 2 y
jeśli potrzebujesz szybko pomnożyć przez potęgę dwóch, ale uważaj na przesunięcie 1-bitowego bitu do górnego bitu - powoduje to, że liczba jest ujemna, chyba że jest bez znaku. Jest to również przydatne w przypadku różnych rozmiarów danych. Na przykład odczyt liczby całkowitej z czterech bajtów:
int val = (A << 24) | (B << 16) | (C << 8) | D;
Zakładając, że A jest najbardziej znaczącym bajtem, a D najmniej. Skończyło się tak:
A = 01000000
B = 00000101
C = 00101011
D = 11100011
val = 01000000 00000101 00101011 11100011
Kolory są często przechowywane w ten sposób (najbardziej znaczący bajt jest ignorowany lub używany jako alfa):
A = 255 = 11111111
R = 21 = 00010101
G = 255 = 11111111
B = 0 = 00000000
Color = 11111111 00010101 11111111 00000000
Aby ponownie znaleźć wartości, po prostu przesuń bity w prawo, aż znajdą się na dole, a następnie zamaskuj pozostałe bity wyższego rzędu:
Int Alpha = Color >> 24
Int Red = Color >> 16 & 0xFF
Int Green = Color >> 8 & 0xFF
Int Blue = Color & 0xFF
0xFF
jest taki sam jak 11111111
. Zasadniczo w przypadku Reda zrobiłbyś to:
Color >> 16 = (filled in 00000000 00000000)11111111 00010101 (removed 11111111 00000000)
00000000 00000000 11111111 00010101 &
00000000 00000000 00000000 11111111 =
00000000 00000000 00000000 00010101 (The original value)