Unterschied zwischen >>> und >>


Antworten:


408

>>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 11111111oder -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.


8
Obwohl ich zustimme und zu schätzen weiß, dass arithmetische Verschiebungen verwendet werden können, um vorzeichenbehaftete Zahlen mit zu multiplizieren 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?
Ziggy

11
Warum sagen Sie, dass eine Bitfolge keine Zahl ist? Würden Sie sagen, dass eine Folge von Dezimalstellen keine Zahl ist?
Danben

4
@danben Die Diskussion, ob es sich um eine Zahl handelt oder nicht, ist nur dann sinnvoll, wenn Sie sie mit einem Kontext verknüpfen. Wenn das Internet nur Strom ist, stimme ich zu, dass ein String nur eine Zahl ist.
Bvdb

1
@danben aber eigentlich denke ich, worauf Ziggy sich wirklich bezog (imho), ist, dass a Stringauch als a angesehen werden könnte char[]. Er sagt nicht, dass a charkeine Zahl ist; Er sagt nur, dass es eine vorzeichenlose Nummer ist. Ich denke, dort ist er verloren.
Bvdb

5
@Ziggy ist richtig: Nicht jede Bitfolge ist eine Zahl, und nicht jede Folge von Dezimalstellen ist eine Zahl. Zum Beispiel: Telefonnummern, Postleitzahlen (in vielen Ländern) usw. sind Dezimalstellen, aber es ist nicht sinnvoll, sie zu addieren, zu subtrahieren oder zu multiplizieren, sodass es sich nicht wirklich um Zahlen handelt. Sie sind zufällig Zeichenfolgen mit Dezimalstellen, sollten jedoch als Zeichenfolgen behandelt werden. (Postleitzahlen in Kanada und Großbritannien enthalten Buchstaben und Ziffern.)
jcsahnwaldt sagt GoFundMonica

102

>>>ist unsigned-shift; es wird 0 einfügen >>ist signiert und erweitert das Vorzeichenbit.

JLS 15.19 Schichtarbeiter

Die Schichtoperatoren umfassen Linksverschiebung <<, vorzeichenbehaftete Rechtsverschiebung >>und vorzeichenlose Rechtsverschiebung >>>.

Der Wert von n>>sist nrechtsverschobene sBitpositionen mit Vorzeichenerweiterung .

Der Wert von n>>>sist nrechtsverschobene sBitpositionen 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.

Verwandte Fragen


Ohne Ihre Beispiele würde ich es nicht verstehen.
Mr5 5.

47

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.


12
können Sie mit einem Beispiel erklären
Kasun Siyambalapitiya

1
Ich denke auch, dass Sie ein Beispiel geben sollten.
Bis zum

Ich nehme an, das >>>ist nicht signiert, aber warum 7>>32=7? Ich lief eine Schleife, die jeweils eine Schicht machte, und sah, dass es nach den 32Schichten wieder zu kam 7. Dies kann nur sinnvoll sein, wenn für jede herausgeschobene Zahl ein "äußerer Kreis" eingegeben wird. Nach den 32Schichten erreichte es irgendwie wieder seine Position, aber das macht natürlich immer noch keinen Sinn. Was ist los?
Ian Limarta

@ IanLimarta Nicht? Ich bekomme nur 0. ( for (int i = 7 << 1, j = 0; j < 32; j++) System.out.println(Integer.toString(i >>= 1, 2));) Wenn Sie meinen, warum >>32selbst der ursprüngliche Wert zurückgegeben wird, sehen Sie dies .
Moira

Es tut mir Leid. Ich meinte, warum ist '7 >>> 32 = 7'.
Ian Limarta

40

Die logische Rechtsverschiebung ( v >>> n) gibt einen Wert zurück, bei dem die Bits vum nBitpositionen 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 vum nBitpositionen 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.


38

>>>setzt immer eine 0 in das Bit ganz links, während >>eine 1 oder eine 0 gesetzt wird, je nachdem, welches Vorzeichen es hat.


10

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

Vielen Dank. Ich möchte nur einen Kommentar hinzufügen, um auf die Bitdarstellung für Integer.MAX_VALUE, Integer.MIN_VALUE, -1, 0, 1 zu verweisen . zB : 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
Andy Dong

6

Der logische Operator >>> Nfü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 >>> 1Operation 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 >> 1Operation wird:

-1: 11111111111111111111111111111111
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.