2016-10-07 8 views
2

Ich habe mehrere Fragen zu dem Thema in dem Thema erwähnt (z. B. this one), aber es scheint mir, dass keiner von ihnen dieses Beispiel zur Verfügung gestellt. Ich verwende Java7 und ich möchte eine String was einer hexadezimalen oder eine Dezimalzahl in einen Integer oder Long Wert konvertieren (hängt davon ab, was es darstellt) und ich folgendes tun:Konvertieren von Hex in Java, falscher Wert mit negativen Werten

public Number getIntegerOrLong(String num) { 
    try { 
     return Integer.decode(num); 
    } catch (NumberFormatException nf1) { 
     final long decodedLong = Long.decode(num); 
     if ((int) decodedLong == decodedLong) {//used in Java8 java.util.Math.toIntExact() 
      return (int) decodedLong; 
     } 
     return decodedLong; 
    } 
} 

Wenn ich einen String verwenden darstellt Wenn ich eine Dezimalzahl alles ist in Ordnung, das Problem mit negativen hexadezimal

Jetzt entstehen, tun:

String hex = "0x"+Integer.toHexString(Integer.MIN_VALUE); 
Object number = getIntegerOrLong(hex); 
assertTrue(number instanceof Integer): 

fehlschlägt, weil es eine Long zurückgibt. Gleiches gilt für andere negative ganzzahlige Werte.

Außerdem, wenn ich Long.MIN_VALUE wie im folgenden Beispiel:

String hex = "0x"+Integer.toHexString(Long.MIN_VALUE); 
Object number = getIntegerOrLong(hex); 
assertTrue(number instanceof Long): 

ausfällt, wegen NumberFormatException mit Nachricht:

java.lang.NumberFormatException: For input string: "8000000000000000" 

Ich versuchte auch mit anderen zufälligen Long Werte (so im Lang .MIN_VALUE und Long.MAX_VALUE, und es schlägt auch fehl, wenn ich negative Zahlen habe, zB

die String mit dem hexadezimalen 0xc0f1a47ba0c04d89 für die Long Nummer -4,543,669,698,155,229,815 kehrt:

java.lang.NumberFormatException: For input string: "c0f1a47ba0c04d89" 

Wie kann ich das Skript beheben, um das gewünschte Verhalten zu erhalten?

+0

@Aaron, tut mir leid, schlechte Typisierung. Ich mache '" 0x "+ Integer.toHexString (Integer.MIN_VALUE)'. Ist das auch schlecht? –

Antwort

2

Long.decode und Integer.decode nicht akzeptieren komplementierten Werte wie durch Integer.toHexString zurückgegeben: das Zeichen sollte als führendes - dargestellt werden, wie durch die DecodableString Grammatiken in den javadoc gefunden beschrieben.

Die Folge von Zeichen im Anschluss an einem optionales Zeichen und/oder radix Spezifizierer („0x“, „0X“, „#“ oder führender Null), wie durch die Long.parseLong Methode mit dem angegebenen radix geparst (10, 16 oder 8). Diese Zeichenfolge muss einen positiven Wert darstellen oder eine NumberFormatException wird ausgelöst. Das Ergebnis wird negiert, wenn erste Zeichen des angegebenen String ist das Minuszeichen

Wenn Sie das Format Ihrer Eingabe String ändern können, dann produzieren sie mit Integer.toString(value, 16) statt Integer.toHexString(value). Wenn Sie zu Java 8 wechseln können, verwenden Sie parseUnsignedInt/Long.

+0

Ich kann BigInteger nicht zur Abwärtskompatibilität zurückgeben. Für die Besetzung habe ich in dem Beispiel, das ich eingegeben habe, einen Fehler gemacht, tatsächlich habe ich "0x" + Integer.toHexString (Integer.MIN_VALUE) 'und" 0x "+ Long.toHexString (Long.MIN_VALUE)' –

+0

I gemacht bin mir nicht sicher, was du genau vorschlägst. Zum Beispiel, wenn Sie 'Long.parseUnsignedLong (Long.toString (Long.MIN_VALUE, 16), 16)' Sie immer noch eine n Ausnahme, das heißt 'java.lang.NumberFormatException: Unzulässiges führendes Minuszeichen bei nicht signierter Zeichenkette -8000000000000000' –

+0

Ich kann bestätigen, dass 'Long.parseUnsignedLong (Long.toHexString (Long.MIN_VALUE), 16)' funktioniert (sowie das 'Integer'-Pendant) –