2012-06-06 8 views
100

Ich versuche die Shift-Operatoren zu verstehen und konnte nicht viel bekommen. Als ich versuchte, den Code untenWie funktionieren Schichtoperatoren in Java?

System.out.println(Integer.toBinaryString(2 << 11)); 
System.out.println(Integer.toBinaryString(2 << 22)); 
System.out.println(Integer.toBinaryString(2 << 33)); 
System.out.println(Integer.toBinaryString(2 << 44)); 
System.out.println(Integer.toBinaryString(2 << 55)); 

ich die unten

1000000000000  
100000000000000000000000  
100  
10000000000000  
1000000000000000000000000  

Könnte jemand ausführen bitte erklären?

+14

Linksverschiebung ist das gleiche wie mit 2 multipliziert, während Verschiebung nach rechts durch integer divide 2. ist – m0skit0

Antwort

162
System.out.println(Integer.toBinaryString(2 << 11)); 

Verschiebt die Binärzahl 2 (10) um das 11-fache nach links. Daraus folgt: 1000000000000

System.out.println(Integer.toBinaryString(2 << 22)); 

Shifts binär 2 (10) um 22 mal nach links. Daraus folgt: 100000000000000000000000

System.out.println(Integer.toBinaryString(2 << 33)); 

Nun, int ist aus 4 Bytes, also 32 Bits. Also, wenn Sie um 33 verschieben, ist es gleichbedeutend mit Verschiebung um 1. Daher: 100

+3

Java definiert Verschiebung zu Maske (Wrap around) der Countdown bis in den Bereich von 0 bis 31 statt Sättigung bis 32 (wenn Verschiebung um 32 nur Nullen übrig). (Offensichtlich zum Beispiel mit 32-Bit-Typen.) Ich gehe davon aus, dass diese Entscheidung getroffen wurde, um das Verhalten der x86-Shift & Rotate-Anweisungen anzupassen. Im Vergleich dazu ist in C die Verschiebung um "count> = type width" Undefined Behavior. (Siehe http://stackoverflow.com/questions/776508/best-practices-for-circular-shift-rotate-operations-in-c für die Art von Workaround, die erforderlich ist, um eine sichere Rotation in C zu codieren.) –

+0

Was ist das? Zweck obwohl?Wie kann ich heutzutage einfach nicht die Verwendung von Bits sehen, außer wenn du Maschinensprache oder etwas richtig machst? – carinlynchin

28

2 aus Dezimalzahl Nummerierungssystem binär als

10 
folgt ist

jetzt, wenn Sie

2 << 11 

tun wäre es, 11 Nullen würde auf der rechten Seite aufgefüllt werden

1000000000000 

Der unterschriebene Linksverschiebungsoperator "< < "verschiebt ein Bitmuster nach links, und der vorzeichenbehaftete Rechtsverschiebeoperator" >> "verschiebt ein Bitmuster nach rechts. Das Bitmuster wird durch den linken Operanden und die Anzahl der zu verschiebenden Positionen durch den rechten Operanden angegeben. Die unsigned rechte Shift-Operator ">>>" verschiebt sich um eine Null in der linken Position, während die Position ganz links nach ">>" hängt von Vorzeichenerweiterung [..]

links um 2 ergibt die Multiplikation Verschiebung (* 2) in Begriffe oder arithmetische


Zum Beispiel

2 in binären 10, wenn Sie <<1 tun, die 100 dieist wären 0

4 in binärer 100, wenn Sie <<1 tun, die 1000 wäre die 8 ist


Auch

+0

Vielleicht Hervorhebung wert, dass „2 in * Binärformat * ist ...“ – adarshr

+0

@adarshr ja

+0

'' a Guter Trick! :) – adarshr

2

Sehen Sie die Bits verschiebt durch Auffüllen so viele 0's.

Für ex,

  • binäre 10, die durch 2 Ziffern 2 Linksverschiebung ist 1000 die digit 8
  • binäre 10 ist, die durch 3-stellige 2 Linksverschiebung ist 10000 die Ziffer ist 16
13

Right und Left Schicht funktionieren auf die gleiche Weise hier ist wie Right Shift funktioniert; Die rechte Verschiebung: Der Operator für die rechte Verschiebung, >>, verschiebt alle Bits in einem Wert eine bestimmte Anzahl von Malen nach rechts. Seine allgemeine Form:

Hier gibt num die Anzahl der Positionen an, um den Wert in Wert zu verschieben. Das heißt, das >> verschiebt alle Bits in dem angegebenen Wert nach rechts um die Anzahl der Bitpositionen, die durch num spezifiziert sind. Das folgende Codefragment verschiebt den Wert 32 nach rechts um zwei Positionen, die sich in einem bis 8 eingestellt wird:

int a = 32; 
a = a >> 2; // a now contains 8 

Wenn ein Wert Bits, die „verschoben off“, jene Bits verloren gehen. Beispielsweise verschiebt sich das nächste Codefragment den Wert 35 an den rechten zwei Positionen, die die zwei Bits niedriger Ordnung bewirkt verloren werden, was wiederum in einer zu 8.

int a = 35; 
a = a >> 2; // a still contains 8 

Mit Blick auf die gleiche Betrieb gesetzt wird, in binären zeigt deutlicher, wie dies geschieht:

00100011 35 >> 2 
00001000 8 

Jedesmal, wenn Sie einen Wert nach rechts verschieben, teilt sie diesen Wert von zwei und verwirft jeden Rest. Sie können dies für die Hochleistungs-Ganzzahl-Division durch 2 nutzen. Natürlich müssen Sie sicher sein, dass Sie keine Bits vom rechten Ende verschieben. Wenn Sie nach rechts verschieben, werden die oberen (am weitesten links liegenden) Bits, die von der rechten Verschiebung freigelegt wurden, mit dem vorherigen Inhalt des oberen Bits gefüllt. Dies wird als Zeichenerweiterung bezeichnet und dient dazu, das Vorzeichen negativer Zahlen zu erhalten, wenn Sie sie nach rechts verschieben. Zum Beispiel –8 >> 1 ist –4, die in binärer ist

11111000 –8 >>1 
11111100 –4 

Es ist interessant zu bemerken, dass, wenn Sie verschieben -1 rechts, bleibt das Ergebnis immer -1, da hält Vorzeichenerweiterung in mehr Einsen in die bringen höherwertige Bits. Manchmal ist es nicht wünschenswert, Werte zu signieren, wenn Sie sie nach rechts verschieben. Beispielsweise konvertiert das folgende Programm einen Byte-Wert in seine hexadezimale Zeichenfolgendarstellung.Beachten Sie, dass der verschobene Wert maskiert wird, indem Sie ihn mit 0x0f UND-verknüpft werden, um alle Zeichenerweiterungsbits zu verwerfen, sodass der Wert als Index in das Array von Hexadezimalzeichen verwendet werden kann.

// Masking sign extension. 
class HexByte { 
    static public void main(String args[]) { 
    char hex[] = { 
     '0', '1', '2', '3', '4', '5', '6', '7', 
     '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' 
    }; 
    byte b = (byte) 0xf1; 
System.out.println("b = 0x" + hex[(b >> 4) & 0x0f] + hex[b & 0x0f]); 
} 
} 

Hier ist die Ausgabe dieses Programms:

b = 0xf1 
11

Ich glaube, das helfen könnten:

System.out.println(Integer.toBinaryString(2 << 0)); 
    System.out.println(Integer.toBinaryString(2 << 1)); 
    System.out.println(Integer.toBinaryString(2 << 2)); 
    System.out.println(Integer.toBinaryString(2 << 3)); 
    System.out.println(Integer.toBinaryString(2 << 4)); 
    System.out.println(Integer.toBinaryString(2 << 5)); 

Ergebnis

10 
    100 
    1000 
    10000 
    100000 
    1000000 

Edited:

Must Read This (how-do-the-bitwise-shift-operators-work)

+0

Sie müssen Schleife für diese –

+4

Ja bevorzugen. Tatsächlich. Ich wollte das einfach so verstehen. – Hashmap

2

Die Verschiebung kann mit Datentypen (char, int und long int) implementieren sein. Die Float- und Double-Daten können nicht verschoben werden.

value= value >> steps // Right shift, signed data. 
value= value << steps // Left shift, signed data. 
6

denke ich, es wäre folgend sein, zum Beispiel:

  • Signed Linksverschiebung

[2 < < 1] => [10 (binär von 2) addiere 1 Null am Ende der binären Kette] Somit wird 10 zu 100, was zu 4 wird.

Signiert links Verschiebung verwendet Multiplikation ... So könnte dies auch als 2 * berechnet werden (2^1) = 4. Ein weiteres Beispiel [ < < 11] = * (2^11) = 4096

  • vorzeichenbehafteten Rechtsverschiebungs-

[4 >> 1] => [100 (binär 4) entfernen, um 1 Null am Ende des Binärstring] Daher wird 100 10 sein, die 2 wird.

Signed Rechtsverschiebung verwendet Division ... So dies auch als 4/(2^1) = 2 Ein weiteres Beispiel [ >> 11] =/(2^11) = 2 berechnet werden

Verwandte Themen