Podczas tej lekcji zapoznasz się z koncepcją operatorów bitowych Java i dowiesz się, na przykładach, jak ich używać. Prawdopodobnie znasz słowo "bit". Jeśli nie, przypomnijmy sobie co ono oznacza :)
Bit to najmniejsza jednostka informacji w komputerze. Jego nazwa pochodzi od binary digit (cyfra binarna). Bit można wyrazić jedną z dwóch liczb: 1 lub 0. Istnieje specjalny system liczb binarnych oparty na zerach i jedynkach.
Nie będziemy zagłębiać się tu w matematyczną dżunglę. Zauważmy tylko, że dowolną liczbę w Javie można przekonwertować na postać binarną. Aby to zrobić, musisz użyć klas osłonowych.
Oto przykład jak możesz zrobić to dla int:
A teraz bierzemy każdy z naszych bitów i dosłownie przesuwamy go w lewo o 3 miejsca:
Spójrzmy co otrzymaliśmy. Jak widać wszystkie nasze bity zostały przesunięte, a od krawędzi zakresu dodano kolejne 3 zera. Trzy, bo wykonaliśmy przesunięcie o 3. Gdybyśmy przesunęli się o 10, dodalibyśmy 10 zer.
Zatem wyrażenie x << y oznacza "przesunięcie bitów liczby x w lewo o y miejsc". Wynik naszego wyrażenia to liczba 1000000000, czyli 512 w systemie dziesiętnym.
Sprawdźmy:
Odpowiada to oczywiście liczbie 0 w systemie dziesiętnym.
Oto prosta zasada do zapamiętania przesunięć w lewo:
Przy każdym przesunięciu w lewo liczba jest mnożona przez 2.
Spróbujmy obliczyć następujące wyrażenie bez ilustracji pokazujących bity
111111111 << 3
Musimy pomnożyć liczbę 111111111 przez 2 odpowiednią liczbę razy. W rezultacie otrzymamy 888888888. Napiszmy trochę kodu i sprawdźmy:
![Operatory bitowe w Javie - 5]()
W wyniku przesunięcia o 2 w prawo, dwa skrajne zera w naszej liczbie przesuwają się poza zakres i giną. Otrzymujemy 10000, co odpowiada liczbie 16 w systemie dziesiętnym.
Wyświetlone zostanie:
Kolejność wykonywania operatorów
Wszystkie operacje są wykonywane od lewej do prawej, z uwzględnieniem ich pierwszeństwa.
Na przykład, jeśli napiszemy
Uff! To była długa lekcja, ale udało się! Jeśli nie do końca rozumiesz część tej lub poprzednich lekcji, nie martw się. Będziemy poruszać te tematy jeszcze nie raz w przyszłości.
Kilka lekcji CodeGym o operacjach logicznych i numerycznych. Nie przejdziemy do nich w najbliższym czasie, ale nie zaszkodzi przeczytać je teraz.

public class Main {
public static void main(String[] args) {
int x = 342;
System.out.println(Integer.toBinaryString(x));
}
}
Wyświetlone zostanie:
101010110
1010 10110 (dodałem spację, aby ułatwić czytanie) to liczba 342 w systemie dziesiętnym. Właściwie podzieliliśmy tę liczbę na poszczególne bity: zera i jedynki. Operacje wykonywane na bitach nazywamy bitowymi.- ~ — negacja bitowa.
101010110 to 342 jako liczba binarna
010101001 to wartość wyrażenia ~342
Spróbujmy zastosować to w praktyce:
public class Main {
public static void main(String[] args) {
int x = 342;
System.out.println(~x);
}
}
Wyświetlone zostanie:
169
169 to wynik (010101001) w dobrze nam znanym systemie dziesiętnym :)- & — koniunkcja bitowa (AND)
110110000 to 277 reprezentowane jako liczba binarna
1000101011 to 432 reprezentowane jako liczba binarna
Następnie operator & porównuje pierwszy bit górnej liczby z pierwszym bitem dolnej liczby. Ponieważ jest to operator AND, wynik będzie równy 1 tylko wtedy, gdy oba bity będą równe 1. W każdym innym przypadku wynik to 0.
100010101
&
110110000
_______________
10001000 — wynik działania operatora &
Najpierw porównujemy pierwszy bit obu liczb, potem drugi bit, potem trzeci i tak dalej.
Jak widać, tylko w dwóch przypadkach oba odpowiadające sobie bity w liczbach są równe 1 (pierwszy i piąty bit). Wszystkie inne porównania dają wynik 0.
Więc ostatecznie otrzymaliśmy liczbę 10001000. W systemie dziesiętnym odpowiada to liczbie 272. Sprawdźmy:
public class Main {
public static void main(String[] args) {
System.out.println(277&432);
}
}
Wyświetlone zostanie:
272
- | — bitowa alternatywa (OR).
public class Main {
public static void main(String[] args) {
System.out.println(277|432);
}
}
Wyświetlone zostanie:
437
Wszystko obliczyliśmy poprawnie! :)- ^ — bitowa alternatywa wykluczająca XOR (exclusive OR)
public class Main {
public static void main(String[] args) {
System.out.println(277^432);
}
}
Wyświetlone zostanie:
165
Super! Wszystko działa tak jak myśleliśmy :)
Czas zapoznać się z operatorami przesunięć bitowych.
Nazwa mówi sama za siebie. Bierzemy jakąś liczbę i przesuwamy jej bity w lewo lub w prawo :) Zobaczmy, jak to wygląda:
Przesunięcie w lewo
Przesunięcie bitów w lewo jest sygnalizowane przez << Oto przykład:
public class Main {
public static void main(String[] args) {
int x = 64;//wartość
int y = 3;// odległość przesunięcia
int z = (x << y);
System.out.println(Integer.toBinaryString(x));
System.out.println(Integer.toBinaryString(z));
}
}
W tym przykładzie liczba x = 64 jest nazywana wartością. Przesuwamy bity tej wartości. Przesuniemy bity w lewo (można było to odgadnąć po kierunku operatora <<).
W systemie binarnym liczba 64 = 1000000
Liczba y = 3 nazywana jest odległością przesunięcia. Odległość przesunięcia wskazuje, o ile bitów w prawo/lewo chcesz przesunąć bity liczby x.
W naszym przykładzie przesuniemy je o 3 bity w lewo.
Aby lepiej zrozumieć proces przesuwania, spójrz na ilustrację.
W tym przykładzie używamy wartości int. Int zajmuje 32 bity w pamięci komputera. Tak prezentuje się nasza oryginalna liczba 64:


public class Main {
public static void main(String[] args) {
int x = 64;//wartość
int y = 3;// odległość przesunięcia
int z = (x << y);
System.out.println(z);
}
}
Wyświetlone zostanie:
512
W punkt!
Teoretycznie bity mogłyby być przesuwane w nieskończoność, ale ponieważ działamy na liczbie typu int, mamy do dyspozycji tylko 32 cyfry binarne. Spośród nich 7 jest już zajętych przez 64 (1000000).
Dlatego gdybyśmy przesunęli się o 27 miejsc w lewo, nasza jedynka wyszłaby poza zakres używanego typu danych i zostałaby utracona.
Zostałyby tylko zera!
public class Main {
public static void main(String[] args) {
int x = 64;//wartość
int y = 26;// odległość przesunięcia
int z = (x << y);
System.out.println(z);
}
}
Wyświetlone zostanie:
0
Zgodnie z oczekiwaniem, jedynka wyszła poza 32 dostępne bity i zniknęła. Skończyliśmy z 32-bitową liczbą składającą się tylko z zer.

public class Main {
public static void main(String[] args) {
System.out.println(111111111 << 3);
}
}
Wyświetlone zostanie:
888888888
Przesunięcie w prawo
Ta operacja jest oznaczana przez >>. Robi to samo, ale w przeciwnym kierunku! :) Nie będziemy wyważać otwartych drzwi. Spróbujmy z tym samym int 64.
public class Main {
public static void main(String[] args) {
int x = 64;//wartość
int y = 2;// odległość przesunięcia
int z = (x >> y);
System.out.println(z);
}
}


16
Oto prosta zasada do zapamiętania przesunięć w prawo:
Przy każdym przesunięciu w prawo dzielimy liczbę przez dwa, odrzucając resztę.
Na przykład,
35 >> 2
oznacza, że musimy dwukrotnie podzielić 35 przez 2, odrzucając resztę
35/2 = 17 (odrzuć resztę 1)
17/2 = 8 (odrzuć resztę 1)
Ostatecznie 35 >> 2 powinno być równe 8.
Sprawdźmy:
public class Main {
public static void main(String[] args) {
System.out.println(35 >> 2);
}
}
Wyświetlone zostanie:
8
Kolejność wykonywania operatorów w Javie
Podczas pisania i czytania kodu często można napotkać wyrażenia, które łączą kilka operacji. Bardzo ważne jest, aby rozumieć kolejność, w jakiej zostaną wykonane (w przeciwnym razie wynik może Cię zaskoczyć). Ponieważ w Javie występuje wiele operacji, każdej z nich przypisano miejsce w specjalnej tabeli:Operatory | Kolejność wykonywania |
---|---|
przyrostkowe | expr++ expr-- |
jednoargumentowe | ++expr --expr +expr ~ ! |
multiplikatywne | * / % |
addytywne | + - |
przesunięcia | << >> >>> |
relacyjne | < > <= >= instanceof |
porównania | == != |
bitowa koniunkcja (bitowe AND) | & |
bitowa alternatywa rozłączna (XOR, exclusive OR) | ^ |
bitowa alternatywa (inclusive OR) | | |
logiczna koniunkcja (logiczne AND) | && |
logiczna alternatywa (logiczne OR) | || |
trójargumentowe | ? : |
przypisania | = += -= *= /= %= &= ^= |= <<= >>= >>>= |
int x = 6 - 4/2;
jako pierwsza zostanie wykonana operacja dzielenia (4/2). Została zapisana jako druga ale ma wyższy priorytet.
Nawiasy oznaczają najwyższy priorytet. Pewnie pamiętasz to ze szkoły.
Na przykład, jeśli dodamy je do naszego wyrażenia
int x = (6 - 4)/2;
wtedy jako pierwsze wykonane zostanie odejmowanie, ponieważ jest umieszczone w nawiasach.
Priorytet operatora logicznego && jest raczej niski (patrz tabela), więc zwykle będzie on ostatni.
Na przykład:
boolean x = 6 - 4/2 > 3 && 12*12 <= 119;
To wyrażenie zostanie wykonane w następujący sposób:- 4/2 = 2
boolean x = 6 - 2 > 3 && 12*12 <= 119;
- 12*12 = 144
boolean x = 6 - 2 > 3 && 144 <= 119;
- 6-2 = 4
boolean x = 4 > 3 && 144 <= 119;
Następnie wykonywane są operatory porównania:- 4 > 3 = true
boolean x = true && 144 <= 119;
- 144 <= 119 = false
boolean x = true && false;
I wreszcie operator AND (&&) zostanie wykonany jako ostatni.
boolean x = true && false;
boolean x = false;
Na przykład operator dodawania (+) ma wyższy priorytet niż operator porównania != (nie równe);
Dlatego w wyrażeniu
boolean x = 7 != 6+1;
najpierw wykonana zostanie operacja 6+1, następnie sprawdzenie 7 != 7 (które da wynik false), a na koniec przypisanie wyniku (false) do zmiennej x (ogólnie przypisanie ma najniższy priorytet ze wszystkich operatorów; patrz tabela).

GO TO FULL VERSION