Ich muss eine Zahl in ein vorzeichenloses Byte konvertieren. Die Zahl ist immer kleiner oder gleich 255 und passt daher in ein Byte.
Ich muss dieses Byte auch wieder in diese Zahl konvertieren. Wie würde ich das in Java machen? Ich habe verschiedene Möglichkeiten ausprobiert und keine funktioniert. Folgendes versuche ich jetzt zu tun:
int size = 5;
// Convert size int to binary
String sizeStr = Integer.toString(size);
byte binaryByte = Byte.valueOf(sizeStr);
und nun, um dieses Byte wieder in die Zahl umzuwandeln:
Byte test = new Byte(binaryByte);
int msgSize = test.intValue();
Dies funktioniert natürlich nicht. Aus irgendeinem Grund wird die Zahl immer in konvertiert 65
. Irgendwelche Vorschläge?
Antworten:
Ein Byte ist immer in Java signiert. Sie können den vorzeichenlosen Wert erhalten, indem Sie ihn mit 0xFF binär verknüpfen:
quelle
0xFF
zu einer vorzeichenlosen Ganzzahl? Eine Erklärung wäre wirklich hilfreich.Java 8 bietet
Byte.toUnsignedInt
konvertierenbyte
zuint
durch unsigned Konvertierung. Im JDK von Oracle wird dies einfach implementiert,return ((int) x) & 0xff;
da HotSpot bereits versteht, wie dieses Muster optimiert werden kann, es jedoch auf anderen VMs vorhanden sein kann. Noch wichtiger ist, dass keine Vorkenntnisse erforderlich sind, um zu verstehen, was ein AnruftoUnsignedInt(foo)
bewirkt.Insgesamt Java 8 stellt Methoden zu konvertieren
byte
undshort
zu unsignedint
undlong
, undint
in unsignedlong
. Eine Methode zum Konvertierenbyte
in vorzeichenloseshort
wurde absichtlich weggelassen, da die JVM nurint
undlong
ohnehin Arithmetik bereitstellt .Um ein int wieder in ein Byte umzuwandeln, verwenden Sie einfach einen Cast :
(byte)someInt
. Die resultierende verengende primitive Konvertierung verwirft alle bis auf die letzten 8 Bits.quelle
Wenn Sie nur einen erwarteten 8-Bit-Wert von einem vorzeichenbehafteten int in einen vorzeichenlosen Wert konvertieren müssen, können Sie die einfache Bitverschiebung verwenden:
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
Wenn Sie etwas anderes als
int
den Basistyp verwenden, müssen Sie natürlich den Verschiebungsbetrag anpassen: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.htmlDenken Sie auch daran, dass Sie
byte
type nicht verwenden können . Andernfalls erhalten Sie einen signierten Wert, wie von anderen Antwortenden angegeben. Der kleinste primitive Typ, den Sie zur Darstellung eines 8-Bit-Werts ohne Vorzeichen verwenden können, ist ashort
.quelle
Der
Integer.toString(size)
Aufruf wird in die char-Darstellung Ihrer Ganzzahl konvertiert, dh in das char'5'
. Die ASCII-Darstellung dieses Zeichens ist der Wert 65.Sie müssen die Zeichenfolge zuerst auf einen ganzzahligen Wert zurücksetzen, z. B. mithilfe von
Integer.parseInt
, um den ursprünglichen int-Wert wiederherzustellen.Unter dem Strich ist es für eine vorzeichenbehaftete / vorzeichenlose Konvertierung am besten,
String
das Bild wegzulassen und die Bitmanipulation zu verwenden, wie @JB vorschlägt.quelle
String sizeStr = Integer.toString(size); int sizeInt = Integer.parseInt(sizeStr); byte binaryByte = Byte.valueOf((byte) sizeInt);
String.getBytes()
liefert wiederum die ASCII-Werte der im Text enthaltenen Zeichen , nicht die numerischen Werte der Ziffern. Sie müssen die Zeichenfolge in einen numerischen Wert analysieren , wie oben angedeutet.Die Lösung funktioniert einwandfrei (danke!). Wenn Sie jedoch das Casting vermeiden und die Arbeit auf niedriger Ebene dem JDK überlassen möchten, können Sie Ihre Ints mit einem DataOutputStream schreiben und mit einem DataInputStream zurücklesen. Sie werden automatisch als nicht signiert behandelt Bytes dann:
Zum Konvertieren von Ints in Binärbytes;
Lesen Sie sie zurück in:
Esp. nützlich für den Umgang mit binären Datenformaten (z. B. flache Nachrichtenformate usw.)
quelle
Außer
char
, dass alle anderen numerischen Datentypen in Java signiert sind.Wie in einer vorherigen Antwort erwähnt, können Sie den vorzeichenlosen Wert erhalten, indem Sie eine
and
Operation mit ausführen0xFF
. In dieser Antwort werde ich erklären, wie es passiert.Wenn Ihr Computer 32-Bit ist, benötigt der
int
Datentyp 32-Bit, um Werte zu speichern.byte
benötigt nur 8-Bit.Die
int
Variablei
wird im Speicher wie folgt dargestellt (als 32-Bit-Ganzzahl).Dann wird die
byte
Variableb
dargestellt als:Da
byte
s nicht signiert sind, repräsentiert dieser Wert-22
. (Suchen Sie nach dem 2er-Komplement, um mehr darüber zu erfahren, wie negative Ganzzahlen im Speicher dargestellt werden.)Dann, wenn Sie Casting ist, wird
int
es immer noch sein,-22
weil Casting das Vorzeichen einer Zahl bewahrt.Der gegossene
32-bit
Wert der Operationb
ausführenand
mit0xFF
.Dann bekommst du
234
als Antwort.quelle
Umgang mit Bytes und vorzeichenlosen Ganzzahlen mit BigInteger:
quelle
Auch wenn es zu spät ist, möchte ich meine Meinung dazu abgeben, da dies möglicherweise klarstellt, warum die von JB Nizet gegebene Lösung funktioniert. Ich bin auf dieses kleine Problem gestoßen, als ich an einem Byte-Parser arbeitete und die String-Konvertierung selbst durchführte. Wenn Sie von einem größeren Integraltyp in einen kleineren Integraltyp kopieren, wie in diesem Java-Dokument angegeben, geschieht Folgendes:
https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.3 Bei einer engeren Konvertierung einer vorzeichenbehafteten Ganzzahl in einen integralen Typ T werden einfach alle außer dem n niedrigsten verworfen Ordnungsbits, wobei n die Anzahl der Bits ist, die zur Darstellung des Typs T verwendet werden. Zusätzlich zu einem möglichen Informationsverlust über die Größe des numerischen Werts kann dies dazu führen, dass das Vorzeichen des resultierenden Werts vom Vorzeichen des Eingabewerts abweicht .
Sie können sicher sein, dass ein Byte ein integraler Typ ist, da in diesem Java-Dokument https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html Byte angegeben ist: Der Byte-Datentyp ist ein 8-Bit-Zwei mit Vorzeichen Komplement Ganzzahl.
Wenn Sie also eine Ganzzahl (32 Bit) in ein Byte (8 Bit) umwandeln, kopieren Sie einfach die letzten (niedrigstwertigen 8 Bit) dieser Ganzzahl in die angegebene Bytevariable.
Im zweiten Teil der Geschichte geht es darum, wie unäre und binäre Java-Operatoren Operanden fördern. https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2 Die Erweiterung der primitiven Konvertierung (§5.1.2) wird angewendet, um einen oder beide Operanden wie angegeben zu konvertieren nach folgenden Regeln:
Wenn einer der Operanden vom Typ double ist, wird der andere in double konvertiert.
Wenn einer der Operanden vom Typ float ist, wird der andere in float konvertiert.
Wenn einer der Operanden vom Typ long ist, wird der andere in long konvertiert.
Andernfalls werden beide Operanden in den Typ int konvertiert.
Seien Sie versichert, wenn Sie mit dem integralen Typ int und / oder niedriger arbeiten, wird dieser zu einem int heraufgestuft.
Ich habe mir auch den Kopf darüber gekratzt :). Hier gibt es eine gute Antwort von rgettman. Bitweise Operatoren in Java nur für Integer und Long?
quelle
Wenn Sie die primitiven Wrapper-Klassen verwenden möchten, funktioniert dies, aber alle Java-Typen sind standardmäßig signiert.
quelle
in Java 7
Ergebnis: 254
quelle