Frage

byte x = -1;
for(int i = 0; i < 8; i++)
{
    x = (byte) (x >>> 1);
    System.out.println("X: " + x);
}

Soweit ich es verstehe, speichert Java Daten in zweier Bestimmungen, was bedeutet -1 = 11111111 (laut Wikipedia).

Aus den Java-Dokumenten: "Das Bitmuster wird vom linken Operanden angegeben, und die Anzahl der Positionen, die sich um den rechten Operanden verschieben können. Der nicht signierte rechte Schaltoperator" >>> "verschiebt eine Null in die linke links in die meisten links, verschiebt sich in die links in die höchste Weise. Position, während die Position nach links nach ">>" hängt von der Vorzeichenverlängerung ab ".

Was bedeutet, dass >>> jedes Mal eine 0 nach links schalten würde. Ich erwarte also, dass dieser Code ist

Iteration: Bitdarstellung von x

0: 11111111

1: 01111111

2: 00111111

3: 00011111

...demnächst

Meine Ausgabe ist jedoch immer x: -1, was bedeutet (ich denke), dass >>> das Zeichenbit in die links am meisten Position steckt. Also versuche ich dann >> und gleiches Ergebnis.

Was ist los? Ich würde erwarten, dass meine Ausgabe: x: -1, x: 127, x: 63 usw.

War es hilfreich?

Lösung

Wer auch immer dachte, dass Bytes unterschrieben werden sollten, wenn Java erfunden wurde

Sie können das tun, was Sie wollen, indem Sie sich auf einen int einwirken und sicherstellen, dass Sie nie eine 1 in das oberste Stück verschieben, so etwas wie folgt:

byte x = -1;
int x2 = ((int)x) & 0xff;
for(int i = 0; i < 8; i++)
{
    x2 = (x2 >>> 1);
    System.out.println("X: " + x2);
}

Ihr spezielles Problem ist, dass >>> sich auf eine INT auswirkt, um die Verschiebung zu machen, dann wirft Sie sie zurück in ein Byte, wie hier gezeigt:

byte x = -1;
int x2 = ((int)x) & 0xff;
int x3;
int x4 = x2;
for(int i = 0; i < 8; i++)
{
    x2 = (x2 >>> 1);
    System.out.println("X2: " + x2);
    x3 = (x >>> 1);
    x = (byte)x3;
    x4 = (x4 >>> 1);
    System.out.println("X: " + x3 + " " + x + " " + x4);
}

Welche Ausgaben:

X2: 127
X: 2147483647 -1 127
X2: 63
X: 2147483647 -1 63
X2: 31
X: 2147483647 -1 31
X2: 15
X: 2147483647 -1 15
X2: 7
X: 2147483647 -1 7
X2: 3
X: 2147483647 -1 3
X2: 1
X: 2147483647 -1 1
X2: 0
X: 2147483647 -1 0

Sie können deutlich sehen, dass X und X3 nicht funktionieren (obwohl X3 korrekt verschiebt wird, setzt es wieder auf Byte, es auf -1). x4 funktioniert perfekt.

Andere Tipps

Erinnere dich daran:

  • Operanden von Bitgewise Operations sind immer zu mindestens einem int befördert!
  • Abgüsse beinhalten immer Zeichenerweiterung.

Wenn Sie also (x >>> n), obwohl Sie X als Byte definiert haben, für die Zwecke der Verschiebung, wird es zunächst in ein INT konvertiert. Wenn das zu konvertierende Byte negativ ist, werden alle "zusätzlichen Bits" (also die meisten linken 24 Bit des resultierenden int) hinzugefügt, um es bis zu einem INT aufzunehmen, auf 1. oder einen anderen Weg, falls das Original Byte war -1, das, was Sie tatsächlich verändern, ist -1 als int, dh 32-Bit-Nummer mit allen 32 Bits auf 1 gesetzt. Wenn Sie dieses Recht um 1-8 Stellen verschieben Bei allen 8 Bits auf 1 oder mit anderen Worten ein Bytewert von -1.

Ich bin mir darüber nicht sicher. Aber ich vermute das ist das

x >>> 1 

wird von Byte zu einem int befördert, weil das wörtliche "1" ein int ist. Was Sie dann beobachten, macht Sinn.

Ich weiß nicht, warum es nicht funktioniert, aber ein einfacher Weg, um das obere Bit zu löschen, ist und mit (binär) 0111111:

x = (byte) (x >>> 1) & 0x7F;

Das Problem ist, wie bereits vor (vor langer Zeit) erzählt, dass X vor der Verschiebung auf int (signtedend) aufgerüstet wird.
Eine "Bit-to-Bit" -Ver Conversion sollte helfen:

byte x = -1;
for(int i = 0; i < 8; i++)
{
    x = (byte) ((x & 0xFF) >>> 1);
    System.out.println("X: " + x);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top