Warum entspricht 11010100 << 1 110101000, nicht 10101000?

40

Warum, wenn ich versuche, Bits für 11010100 2 zu verschieben , ist das Ergebnis 110101000 2 , nicht 10101000 2 .

int a = Integer.parseInt("11010100", 2) << 1;

Ich versuche das zu tun:

int a = (byte)(Integer.parseInt("11010100", 2) << 1);

Wenn der Ausgabewert jedoch größer als 128 ist, geht alles in ein Minus, was logisch ist. Wie kann ich dafür sorgen, dass sich die Anzahl der Bits nicht ändert?

Yaroshenko Yaroslav
quelle
4
Ganzzahlige Arithmetik wird immer für ints oder longs ausgeführt.
Tom Hawtin - Tackline
34
Sie verwenden Ganzzahlen, die 32 Bit lang sind. Warum sollten Sie erwarten, dass das Ergebnis auf 8 Bit abgeschnitten wird?
Jhamon
1
Byte a = ... wird es beheben.
Perdi Estaquel

Antworten:

61

Lassen Sie es uns Schritt für Schritt machen.

  1. Integer.parseInt("11010100", 2)- das ist der int-Wert 212. Das ist übrigens unnötig; Sie können einfach schreiben : 0b11010100.

  2. 0b11010100 << 1ist das gleiche wie 0b110101000und ist 424.

  3. Sie wandeln es dann in ein Byte um : (byte)(0b11010100 << 1). Die Bits jenseits der ersten 8 werden alle abgeschnitten, wodurch 0b10101000 übrig bleibt, was -88 ist. Minus, ja, weil in Java Bytes signiert sind.

  4. Sie setzen diese -88 dann stillschweigend wieder auf int zurück, während Sie sie einem int-Wert zuweisen. Es bleibt -88, was bedeutet, dass alle oberen Bits alle 1s sind.

Daher ist der Endwert -88.

Wenn Sie 168stattdessen sehen möchten (was genau die gleichen Bits sind, aber ohne Vorzeichen statt mit Vorzeichen angezeigt werden), verwenden Sie den üblichen Trick & 0xFF, bei dem alle Bits außer den ersten 8 auf 0 gesetzt werden, wodurch eine positive Zahl garantiert wird:

byte b = (byte) (0b11010100 << 1);
System.out.println(b); // -88. It is not possible to print 168 when printing a byte.
int asUnsigned = b & 0xFF;
System.out.println(asUnsigned); // 168.

// or in one go:

System.out.println(((byte) (0b11010100 << 1)) & 0xFF); // 168
rzwitserloot
quelle
19
Er speichert den Wert in int a. Wenn Sie also haben & 0xFF, müssen Sie überhaupt nicht wirken. int a = (0b11010100<< 1) & 0xFF;
Mooing Duck
9

Wenn Sie alle Bits auf 0 setzen möchten, die höher als die unteren 8 Bits sind, können Sie das bitweise UND verwenden:

int a = (Integer.parseInt("11010100", 2) << 1) & 0xff;
System.out.println (Integer.toString(a,2));

Ausgabe:

10101000
Eran
quelle
6

Versuchen Sie so etwas:

int anInt = Integer.parseInt("11010100", 2) << 1;
int asUnsignedInt= Byte.toUnsignedInt((byte) anInt);

toUnsignedInt wurde in Java SE 8 eingeführt.

Puce
quelle