int i =132;
byte b =(byte)i; System.out.println(b);
Verblüffend. Warum ist die Ausgabe -124
?
In Java int
ist an 32 Bit. A byte
ist 8 bits
.
Die meisten primitiven Typen in Java angemeldet sind, und byte
, short
, int
und long
werden in Zweier-Komplement codiert. (Der char
Typ ist nicht signiert und das Konzept eines Zeichens gilt nicht für boolean
.)
In diesem Zahlenschema gibt das höchstwertige Bit das Vorzeichen der Zahl an. Wenn mehr Bits benötigt werden, wird das höchstwertige Bit ("MSB") einfach in das neue MSB kopiert.
Wenn Sie also Byte haben 255
: 11111111
und es als int
(32 Bit) darstellen möchten, kopieren Sie einfach die 1 24 Mal nach links.
Eine Möglichkeit, die Komplementzahl einer negativen Zwei zu lesen, besteht darin, mit dem niedrigstwertigen Bit zu beginnen, nach links zu gehen, bis Sie die erste 1 finden, und anschließend jedes Bit zu invertieren. Die resultierende Zahl ist die positive Version dieser Zahl
Zum Beispiel: 11111111
geht zu 00000001
= -1
. Dies ist, was Java als Wert anzeigt.
Was Sie wahrscheinlich tun möchten, ist den vorzeichenlosen Wert des Bytes zu kennen.
Sie können dies mit einer Bitmaske erreichen, die alles außer den niedrigstwertigen 8 Bits löscht. (0xff)
So:
byte signedByte = -1;
int unsignedByte = signedByte & (0xff);
System.out.println("Signed: " + signedByte + " Unsigned: " + unsignedByte);
Würde ausdrucken: "Signed: -1 Unsigned: 255"
Was passiert hier eigentlich?
Wir verwenden bitweises UND, um alle Fremdzeichenbits zu maskieren (die Einsen links von den niedrigstwertigen 8 Bits). Wenn ein int in ein Byte konvertiert wird, schneidet Java die 24 Bits ganz links ab
1111111111111111111111111010101
&
0000000000000000000000001111111
=
0000000000000000000000001010101
Da das 32. Bit jetzt das Vorzeichenbit anstelle des 8. Bits ist (und wir das Vorzeichenbit auf 0 setzen, was positiv ist), werden die ursprünglichen 8 Bits aus dem Byte von Java als positiver Wert gelesen.
signedByte & (0xff)
ist, dass0xff
es sich um ein Interger-Literal handelt. SignedByte wird daher zu einer Ganzzahl heraufgestuft, bevor die bitweise Operation ausgeführt wird.132
in Ziffern ( Basis 10 ) ist1000_0100
in Bits ( Basis 2 ) und Java speichertint
in 32 Bits:Der Algorithmus für Int-to-Byte ist links abgeschnitten. Der Algorithmus für
System.out.println
ist das Zweierkomplement (das Zweierkomplement ist, wenn das Bit ganz links ist1
, als negatives Einerkomplement (invertierte Bits) minus eins zu interpretieren .); AlsoSystem.out.println(int-to-byte(
))
ist:0000_0000_0000_0000_0000_0000_1000_0100
) [)))])1000_0100
[)))])1000_0100
))))1000_0011
)))0111_1100
))quelle
0
für positiv und1
für negativ).int
nach abyte
ist eine verlustbehaftete Konvertierung (dh Informationen gehen verloren). Daher gibt es keine Möglichkeit, es wieder in seinen ursprünglichenint
Wert umzuwandeln .Das Byte in Java ist signiert, hat also einen Bereich von -2 ^ 7 bis 2 ^ 7-1 - dh -128 bis 127. Da 132 über 127 liegt, werden Sie am Ende um 132-256 = -124 gewickelt. Das heißt, im Wesentlichen werden 256 (2 ^ 8) addiert oder subtrahiert, bis sie in den Bereich fallen.
Für weitere Informationen möchten Sie vielleicht das Zweierkomplement nachlesen .
quelle
132 liegt außerhalb des Bereichs eines Bytes, das zwischen -128 und 127 liegt (Byte.MIN_VALUE bis Byte.MAX_VALUE). Stattdessen wird das oberste Bit des 8-Bit-Werts als Vorzeichen behandelt, was anzeigt, dass es in diesem Fall negativ ist. Die Zahl ist also 132 - 256 = -124.
quelle
Hier ist eine sehr mechanische Methode ohne die ablenkenden Theorien:
Diese praktischere Methode entspricht den vielen theoretischen Antworten oben. Wenn Sie also noch die Java-Bücher lesen, in denen es heißt, Modulo zu verwenden, ist dies definitiv falsch, da die oben beschriebenen 4 Schritte definitiv keine Modulo-Operation sind.
quelle
http://iiti.ac.in/people/~tanimad/JavaTheCompleteReference.pdf
Seite 59Zweierkomplement Gleichung:
In Java werden
byte
(N = 8) undint
(N = 32) durch das oben gezeigte 2s-Komplement dargestellt.Aus der Gleichung ergibt sich eine 7 negativ für,
byte
aber positiv fürint
.quelle
Oft finden Sie in Büchern die Erklärung für das Casting von int nach byte als durch Modulteilung ausgeführt. Dies ist nicht genau richtig, wie unten gezeigt. Was tatsächlich passiert, ist, dass die 24 höchstwertigen Bits aus dem Binärwert der int-Zahl verworfen werden, was Verwirrung stiftet, wenn das verbleibende Bit ganz links gesetzt wird, das die Zahl als negativ bezeichnet
quelle
Ein schneller Algorithmus, der die Funktionsweise simuliert, ist folgender:
Wie funktioniert das? Schauen Sie auf daixtr Antwort. Eine Implementierung des genauen Algorithmus, der in seiner Antwort beschrieben ist, ist die folgende:
quelle
Wenn Sie dies mathematisch verstehen möchten, wie dies funktioniert
Im Grunde genommen werden die Zahlen s / w -128 bis 127 genauso geschrieben wie ihr Dezimalwert, über dem Wert (Ihre Zahl - 256).
z.B. 132 wird die Antwort 132 - 256 = - 124 sein, dh
256 + Ihre Antwort in der Zahl 256 + (-124) ist 132
Ein anderes Beispiel
Die Ausgabe wird 39 44 sein
(295 - 256) (300 - 256)
HINWEIS: Zahlen nach der Dezimalstelle werden nicht berücksichtigt.
quelle
Konzeptionell werden wiederholte Subtraktionen von 256 von Ihrer Zahl vorgenommen, bis sie im Bereich von -128 bis +127 liegt. In Ihrem Fall beginnen Sie also mit 132 und enden dann in einem Schritt mit -124.
Rechnerisch entspricht dies dem Extrahieren der 8 niedrigstwertigen Bits aus Ihrer ursprünglichen Nummer. (Und beachten Sie, dass das höchstwertige Bit dieser 8 das Vorzeichenbit wird.)
Beachten Sie, dass dieses Verhalten in anderen Sprachen nicht definiert ist (z. B. C und C ++).
quelle
quelle