Antworten:
>>
ist arithmetische Verschiebung nach rechts, >>>
ist logische Verschiebung nach rechts.
Bei einer arithmetischen Verschiebung wird das Vorzeichenbit erweitert, um die Vorzeichen der Zahl zu erhalten.
Zum Beispiel: -2 in 8 Bits dargestellt wäre 11111110
(weil das höchstwertige Bit ein negatives Gewicht hat). Wenn Sie es mit der arithmetischen Verschiebung um ein Bit nach rechts verschieben, erhalten Sie 11111111
oder -1. Die logische Rechtsverschiebung kümmert sich jedoch nicht darum, dass der Wert möglicherweise eine vorzeichenbehaftete Zahl darstellt. es verschiebt einfach alles nach rechts und füllt von links mit 0s. Eine Verschiebung unserer -2 um ein Bit nach rechts durch logische Verschiebung würde ergeben 01111111
.
2^k
, finde ich es seltsam, dass dies die Antwort aller ist. Eine Bitfolge ist keine Zahl und >>
kann immer für jede Bitfolge verwendet werden: Sie macht immer das Gleiche, unabhängig von der Rolle, die die Bitfolge spielt, und unabhängig davon, ob sie ein Vorzeichenkonzept hat. Wäre es in Ordnung, Ihre bereits gute Antwort mit einer Diskussion des Falls zu erweitern, wenn Ihr Operand nicht als signierte Nummer interpretiert wird? Ist meine Beschwerde sinnvoll?
String
auch als a angesehen werden könnte char[]
. Er sagt nicht, dass a char
keine Zahl ist; Er sagt nur, dass es eine vorzeichenlose Nummer ist. Ich denke, dort ist er verloren.
>>>
ist unsigned-shift; es wird 0 einfügen >>
ist signiert und erweitert das Vorzeichenbit.
Die Schichtoperatoren umfassen Linksverschiebung
<<
, vorzeichenbehaftete Rechtsverschiebung>>
und vorzeichenlose Rechtsverschiebung>>>
.Der Wert von
n>>s
istn
rechtsverschobenes
Bitpositionen mit Vorzeichenerweiterung .Der Wert von
n>>>s
istn
rechtsverschobenes
Bitpositionen mit Null-Erweiterung .
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"
Um die Dinge klarer zu machen, fügen Sie ein positives Gegenstück hinzu
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"
Da es positiv ist, addieren sowohl vorzeichenbehaftete als auch vorzeichenlose Verschiebungen 0 zum Bit ganz links.
1 >>> 32 == 1
Sie sind beide rechtsverschoben, aber es >>>
istunsigned
Aus der Dokumentation :
Der vorzeichenlose Rechtsverschiebungsoperator ">>>" verschiebt eine Null in die Position ganz links, während die Position ganz links nach ">>" von der Vorzeichenerweiterung abhängt.
>>>
ist nicht signiert, aber warum 7>>32=7
? Ich lief eine Schleife, die jeweils eine Schicht machte, und sah, dass es nach den 32
Schichten wieder zu kam 7
. Dies kann nur sinnvoll sein, wenn für jede herausgeschobene Zahl ein "äußerer Kreis" eingegeben wird. Nach den 32
Schichten erreichte es irgendwie wieder seine Position, aber das macht natürlich immer noch keinen Sinn. Was ist los?
Die logische Rechtsverschiebung ( v >>> n
) gibt einen Wert zurück, bei dem die Bits v
um n
Bitpositionen nach rechts verschoben wurden und Nullen von der linken Seite verschoben werden. Ziehen Sie in Betracht, 8-Bit-Werte zu verschieben, die binär geschrieben sind:
01111111 >>> 2 = 00011111
10000000 >>> 2 = 00100000
Wenn wir die Bits als vorzeichenlose nichtnegative Ganzzahl interpretieren, hat die logische Rechtsverschiebung den Effekt, dass die Zahl durch die entsprechende Potenz von 2 geteilt wird. Wenn die Zahl jedoch in Zweierkomplementdarstellung vorliegt, teilt die logische Rechtsverschiebung negative Zahlen nicht korrekt . Zum Beispiel verschiebt sich die zweite Verschiebung nach rechts oben von 128 nach 32, wenn die Bits als vorzeichenlose Zahlen interpretiert werden. Aber es verschiebt sich -128 zu 32, wenn, wie es in Java typisch ist, die Bits im Zweierkomplement interpretiert werden.
Wenn Sie also verschieben, um durch eine Zweierpotenz zu teilen, möchten Sie die arithmetische Rechtsverschiebung ( v >> n
). Es gibt einen Wert zurück, bei dem die Bits v
um n
Bitpositionen nach rechts verschoben wurden und Kopien des am weitesten links liegenden Bits von v von der linken Seite verschoben werden:
01111111 >> 2 = 00011111
10000000 >> 2 = 11100000
Wenn die Bits eine Zahl in Zweierkomplementdarstellung sind, hat die arithmetische Rechtsverschiebung den Effekt, durch eine Zweierpotenz zu teilen. Dies funktioniert, weil das Bit ganz links das Vorzeichenbit ist. Das Teilen durch eine Zweierpotenz muss das Zeichen gleich halten.
Lesen Sie mehr über Bitwise- und Bit Shift-Operatoren
>> Signed right shift
>>> Unsigned right shift
Das Bitmuster wird durch den linken Operanden und die Anzahl der zu verschiebenden Positionen durch den rechten Operanden angegeben. Der vorzeichenlose Rechtsschieber >>>
verschiebt eine Null in die Position ganz links .
während die Position ganz links danach >>
von der Zeichenverlängerung abhängt.
In einfachen Worten verschiebt sich>>>
immer eine Null in die Position ganz links, während sich >>
Verschiebungen basierend auf dem Vorzeichen der Zahl, dh 1 für negative Zahl und 0 für positive Zahl, verschieben.
Versuchen Sie es beispielsweise mit negativen und positiven Zahlen.
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));
Ausgabe:
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
Der logische Operator >>> N
für die Rechtsverschiebung ( ) verschiebt die Bits um N Positionen nach rechts, verwirft das Vorzeichenbit und füllt die N Bits ganz links mit Nullen auf. Zum Beispiel:
-1 (in 32-bit): 11111111111111111111111111111111
nach einer >>> 1
Operation wird:
2147483647: 01111111111111111111111111111111
Der rechtsverschobene arithmetische Operator ( >> N
) verschiebt die Bits ebenfalls um N Positionen nach rechts, behält jedoch das Vorzeichenbit bei und füllt die N am weitesten links liegenden Bits mit Einsen auf. Zum Beispiel:
-2 (in 32-bit): 11111111111111111111111111111110
nach einer >> 1
Operation wird:
-1: 11111111111111111111111111111111