Odpowiedzi:
>>jest przesunięciem arytmetycznym w prawo, >>>jest przesunięciem logicznym w prawo.
W przesunięciu arytmetycznym bit znaku jest przedłużany w celu zachowania podpisu liczby.
Na przykład: -2 przedstawione w 8 bitach byłoby 11111110(ponieważ najbardziej znaczący bit ma wagę ujemną). Przesunięcie go o jeden bit za pomocą przesunięcia arytmetycznego dałoby ci 11111111, lub -1. Logiczne przesunięcie w prawo nie ma jednak znaczenia, że wartość może reprezentować liczbę ze znakiem; po prostu przesuwa wszystko w prawo i wypełnia od lewej zerami. Przesunięcie naszego -2 o jeden bit za pomocą logicznego przesunięcia dałoby 01111111.
2^k, wydaje mi się dziwne, że to odpowiedź wszystkich. Łańcuch bitów nie jest liczbą i >>zawsze można go użyć na dowolnym łańcuchu bitów: zawsze robi to samo bez względu na rolę, jaką odgrywa łańcuch bitów i niezależnie od tego, czy ma pojęcie „znaku”. Czy byłoby dobrze, gdybyś udzielił już i tak doskonałej odpowiedzi, omawiając sprawę, gdy twój operand nie jest interpretowany jako liczba podpisana? Czy moja skarga ma sens?
Stringmożna również uznać za char[]. Nie mówi, że a charnie jest liczbą; on tylko mówi, że jest to liczba bez znaku . Myślę, że tam zginął.
>>>Przesunięcie jest niepodpisane; wstawi 0. >>jest podpisany i rozszerzy bit znaku.
Operatory zmiany obejmują przesunięcie w lewo, przesunięcie w
<<prawo ze znakiem>>i przesunięcie w prawo bez znaku>>>.Wartość
n>>stonprzesunięte w prawospozycje bitów z przedłużeniem znaku .Wartość
n>>>stonprzesunięte w prawospozycje bitów z rozszerzeniem zera .
System.out.println(Integer.toBinaryString(-1));
// prints "11111111111111111111111111111111"
System.out.println(Integer.toBinaryString(-1 >> 16));
// prints "11111111111111111111111111111111"
System.out.println(Integer.toBinaryString(-1 >>> 16));
// prints "1111111111111111"
Aby wyjaśnić, dodając pozytywny odpowiednik
System.out.println(Integer.toBinaryString(121));
// prints "1111001"
System.out.println(Integer.toBinaryString(121 >> 1));
// prints "111100"
System.out.println(Integer.toBinaryString(121 >>> 1));
// prints "111100"
Ponieważ jest to pozytywne, zarówno podpisane, jak i niepodpisane przesunięcia dodadzą 0 do lewego końca.
1 >>> 32 == 1Oba są przesunięte w prawo, ale tak >>>jestunsigned
Z dokumentacji :
Niepodpisany operator przesunięcia w prawo „>>>” przesuwa zero w skrajne lewe położenie, natomiast skrajne lewe położenie po „>>” zależy od rozszerzenia znaku.
>>>to niepodpisane, ale dlaczego 7>>32=7? Przebiegłem pętlę, która zmieniała się jedna po drugiej i zobaczyłem, że po 32zmianie wrócił do 7. Jedynym sposobem, który może to mieć sens, jest to, że dla każdej przesuniętej liczby wchodziła ona w „zewnętrzny krąg”. Po 32zmianach w jakiś sposób wrócił do swojej pozycji, ale oczywiście to nadal nie ma sensu. Co się dzieje?
Logiczne przesunięcie w prawo ( v >>> n) zwraca wartość, w której bity vzostały przesunięte w prawo o npozycje bitów, a cyfry 0 są przesunięte z lewej strony. Rozważ przesunięcie wartości 8-bitowych zapisanych w systemie binarnym:
01111111 >>> 2 = 00011111
10000000 >>> 2 = 00100000
Jeśli interpretujemy bity jako niepodpisaną nieujemną liczbę całkowitą, logiczne przesunięcie w prawo powoduje podzielenie liczby przez odpowiadającą jej potęgę 2. Jeśli jednak liczba jest reprezentowana przez uzupełnienie dwóch, logiczne przesunięcie w prawo nie dzieli poprawnie liczb ujemnych . Na przykład drugie przesunięcie w prawo powyżej przesuwa 128 do 32, gdy bity są interpretowane jako liczby bez znaku. Ale przesuwa się z -128 na 32, gdy, jak to jest typowe w Javie, bity są interpretowane jako uzupełnienie dwóch.
Dlatego jeśli przesuwasz się, aby podzielić przez potęgę dwóch, potrzebujesz arytmetycznego przesunięcia w prawo ( v >> n). Zwraca wartość, w której bity vzostały przesunięte w prawo o npozycje bitów, a kopie najbardziej lewego bitu v są przesunięte z lewej strony:
01111111 >> 2 = 00011111
10000000 >> 2 = 11100000
Kiedy bity są liczbą w reprezentacji dwóch uzupełnień, arytmetyczne przesunięcie w prawo powoduje dzielenie przez potęgę dwóch. Działa to, ponieważ skrajnie lewy bit jest bitem znaku. Dzielenie przez potęgę dwóch musi zachować znak bez zmian.
Przeczytaj więcej o operatorach Bitwise i Bit Shift
>> Signed right shift
>>> Unsigned right shift
Wzór bitowy jest podawany przez lewy operand, a liczba pozycji do przesunięcia przez prawy operand. Niepodpisany prawy operator >>> zmiany biegów przesuwa zero na skrajne lewe położenie ,
podczas gdy pozycja najbardziej po lewej >>zależy od rozszerzenia znaku.
W prostych słowach >>>zawsze przesuwa zero do skrajnej lewej pozycji, podczas gdy >>przesuwa się na podstawie znaku liczby, tj. 1 dla liczby ujemnej i 0 dla liczby dodatniej.
Na przykład spróbuj z liczbami ujemnymi i dodatnimi.
int c = -153;
System.out.printf("%32s%n",Integer.toBinaryString(c >>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c >>>= 2));
System.out.println(Integer.toBinaryString(c <<= 2));
System.out.println();
c = 153;
System.out.printf("%32s%n",Integer.toBinaryString(c >>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c >>>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
wynik:
11111111111111111111111111011001
11111111111111111111111101100100
111111111111111111111111011001
11111111111111111111111101100100
100110
10011000
100110
10011000
System.out.println(Integer.MAX_VALUE + ": " + String.format("%32s", Integer.toBinaryString(Integer.MAX_VALUE)).replace(' ', '0')); Integer.MAX_VALUE : 01111111111111111111111111111111; Integer.MIN_VALUE : 10000000000000000000000000000000; -1 : 11111111111111111111111111111111; 0 : 00000000000000000000000000000000; 1 : 00000000000000000000000000000001
Operator logiczny przesunięcia w prawo ( >>> N) przesuwa bity w prawo o N pozycji, odrzucając bit znaku i dopełniając N bitów najbardziej w lewo zerami. Na przykład:
-1 (in 32-bit): 11111111111111111111111111111111
po >>> 1operacji staje się:
2147483647: 01111111111111111111111111111111
Operator arytmetyczny z przesunięciem w prawo ( >> N) również przesuwa bity w prawo o N pozycji, ale zachowuje bit znaku i wypełnia N bitów najbardziej w lewo za pomocą 1. Na przykład:
-2 (in 32-bit): 11111111111111111111111111111110
po >> 1operacji staje się:
-1: 11111111111111111111111111111111