Ich habe den folgenden Code ...
int Val=-32768;
String Hex=Integer.toHexString(Val);
Dies entspricht ffff8000
int FirstAttempt=Integer.parseInt(Hex,16); // Error "Invalid Int"
int SecondAttempt=Integer.decode("0x"+Hex); // Error "Invalid Int"
Zunächst wird der Wert -32768 in eine Hex-Zeichenfolge ffff8000 konvertiert, dann kann die Hex-Zeichenfolge jedoch nicht wieder in eine Ganzzahl konvertiert werden.
Darin .Net
funktioniert es wie erwartet und returns -32768
.
Ich weiß, dass ich meine eigene kleine Methode schreiben könnte, um dies selbst zu konvertieren, aber ich frage mich nur, ob mir etwas fehlt oder ob dies wirklich ein Fehler ist?
int firstAttempt = 5;
Antworten:
Es läuft über, weil die Zahl negativ ist.
Versuchen Sie dies und es wird funktionieren:
int n = (int) Long.parseLong("ffff8000", 16);
quelle
String Hex=Integer.toHexString("xyz");
wie man einen String vom Hex als "xyz"int val = -32768; String hex = Integer.toHexString(val); int parsedResult = (int) Long.parseLong(hex, 16); System.out.println(parsedResult);
So können Sie es machen.
Der Grund, warum es nicht so funktioniert:
Integer.parseInt
Nimmt ein vorzeichenbehaftetes Int undtoHexString
erzeugt ein vorzeichenloses Ergebnis. Wenn Sie also etwas höher als einfügen0x7FFFFFF
, wird automatisch ein Fehler ausgegeben. Wenn Sie eslong
stattdessen als analysieren , wird es weiterhin signiert. Wenn Sie es jedoch auf int zurücksetzen, wird es auf den richtigen Wert überlaufen.quelle
int
zu verhexen:Hex zu
int
:Integer.valueOf(hexString, 16).intValue();
Möglicherweise möchten Sie auch
long
anstelle von verwendenint
(wenn der Wert nicht denint
Grenzen entspricht):Hex zu
long
:Long.valueOf(hexString, 16).longValue()
long
zu Hexquelle
Es ist erwähnenswert, dass Java 8 die Methoden hat
Integer.parseUnsignedInt
undLong.parseUnsignedLong
das tut, was Sie wollten, insbesondere:Integer.parseUnsignedInt("ffff8000",16) == -32768
Der Name ist etwas verwirrend, da er eine vorzeichenbehaftete Ganzzahl aus einer Hex-Zeichenfolge analysiert, aber die Arbeit erledigt.
quelle
Versuchen Sie es mit der BigInteger-Klasse, es funktioniert.
int Val=-32768; String Hex=Integer.toHexString(Val); //int FirstAttempt=Integer.parseInt(Hex,16); // Error "Invalid Int" //int SecondAttempt=Integer.decode("0x"+Hex); // Error "Invalid Int" BigInteger i = new BigInteger(Hex,16); System.out.println(i.intValue());
quelle
Da Integer.toHexString (Byte / Ganzzahl) nicht funktioniert, wenn Sie versuchen, signierte Bytes wie UTF-16-dekodierte Zeichen zu konvertieren, müssen Sie Folgendes verwenden:
Integer.toString(byte/integer, 16);
oder
String.format("%02X", byte/integer);
umgekehrt können Sie verwenden
Integer.parseInt(hexString, 16);
quelle
Javas parseInt-Methode ist eigentlich eine Menge Code, der "falsches" Hex frisst: Wenn Sie -32768 übersetzen möchten, sollten Sie den absoluten Wert in hex konvertieren und dann den String mit '-' voranstellen.
Es gibt ein Beispiel für eine Integer.java-Datei:
public static int parseInt(String s, int radix)
Die Beschreibung ist ziemlich explizit:
* Parses the string argument as a signed integer in the radix * specified by the second argument. The characters in the string ... ... * parseInt("0", 10) returns 0 * parseInt("473", 10) returns 473 * parseInt("-0", 10) returns 0 * parseInt("-FF", 16) returns -255
quelle
Verwenden
Integer.toHexString(...)
ist eine gute Antwort. Aber persönlich lieber verwendenString.format(...)
.Probieren Sie dieses Beispiel als Test aus.
byte[] values = new byte[64]; Arrays.fill(values, (byte)8); //Fills array with 8 just for test String valuesStr = ""; for(int i = 0; i < values.length; i++) valuesStr += String.format("0x%02x", values[i] & 0xff) + " "; valuesStr.trim();
quelle
Der folgende Code würde funktionieren:
int a=-32768; String a1=Integer.toHexString(a); int parsedResult=(int)Long.parseLong(a1,16); System.out.println("Parsed Value is " +parsedResult);
quelle
Hehe, neugierig. Ich denke, das ist sozusagen ein "absichtlicher Fehler".
Der zugrunde liegende Grund ist, wie die Integer-Klasse geschrieben wird. Grundsätzlich ist parseInt für positive Zahlen "optimiert". Wenn die Zeichenfolge analysiert wird, wird das Ergebnis kumulativ erstellt, jedoch negiert. Dann dreht es das Vorzeichen des Endergebnisses um.
Beispiel:
66 = 0x42
analysiert wie:
4*(-1) = -4 -4 * 16 = -64 (hex 4 parsed) -64 - 2 = -66 (hex 2 parsed) return -66 * (-1) = 66
Schauen wir uns nun Ihr Beispiel FFFF8000 an
16*(-1) = -16 (first F parsed) -16*16 = -256 -256 - 16 = -272 (second F parsed) -272 * 16 = -4352 -4352 - 16 = -4368 (third F parsed) -4352 * 16 = -69888 -69888 - 16 = -69904 (forth F parsed) -69904 * 16 = -1118464 -1118464 - 8 = -1118472 (8 parsed) -1118464 * 16 = -17895552 -17895552 - 0 = -17895552 (first 0 parsed) Here it blows up since -17895552 < -Integer.MAX_VALUE / 16 (-134217728). Attempting to execute the next logical step in the chain (-17895552 * 16) would cause an integer overflow error.
Bearbeiten (Hinzufügen): Damit parseInt () für -Integer.MAX_VALUE <= n <= Integer.MAX_VALUE "konsistent" funktioniert, hätte es eine Logik implementieren müssen, um "zu drehen", wenn -Integer.MAX_VALUE in der kumulatives Ergebnis, beginnend am maximalen Ende des ganzzahligen Bereichs und von dort weiter abwärts. Warum sie das nicht taten, musste man Josh Bloch oder denjenigen fragen, der es überhaupt implementiert hatte. Es könnte nur eine Optimierung sein.
Jedoch,
Hex=Integer.toHexString(Integer.MAX_VALUE); System.out.println(Hex); System.out.println(Integer.parseInt(Hex.toUpperCase(), 16));
funktioniert gut, nur aus diesem Grund. In der Quelle für Integer finden Sie diesen Kommentar.
// Accumulating negatively avoids surprises near MAX_VALUE
quelle
// Accumulating negatively avoids surprises near MAX_VALUE
-> aber es