Domanda

public class Main3 {
    public static void main(String[] args) {
        Integer min = Integer.MIN_VALUE;
        String minHex = Integer.toHexString(Integer.MIN_VALUE);

        System.out.println(min + " " + minHex);
        System.out.println(Integer.parseInt(minHex, 16));
    }
}

-2147483648 80000000
Exception in thread "main" java.lang.NumberFormatException: For input string: "80000000"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
    at java.lang.Integer.parseInt(Integer.java:459)
    at Main3.main(Main3.java:7)

Che succede?

È stato utile?

Soluzione

È documentato che Integer.toHexString restituisce una rappresentazione in formato stringa dell'intero come valore senza segno, mentre Integer.parseInt accetta un int firmato. Se invece usi Integer.toString(value, 16) otterrai quello che vuoi.

Altri suggerimenti

Questo è qualcosa che mi ha sempre infastidito. Se si inizializza un int con un valore letterale esadecimale, è possibile utilizzare l'intero intervallo di valori positivi fino a 0xFFFFFF; qualcosa di più grande di 0x7FFFFF sarà davvero un valore negativo. Questo è molto utile per il mascheramento dei bit e altre operazioni in cui ti preoccupi solo delle posizioni dei bit, non del loro significato.

Ma se si utilizza Integer.parseInt () per convertire una stringa in un numero intero, qualsiasi cosa più grande di "0x7FFFFFFF" viene trattata come un errore. Probabilmente c'è una buona ragione per cui l'hanno fatto in quel modo, ma è ancora frustrante.

La soluzione più semplice consiste nell'usare Long.parseLong () invece, quindi eseguire il cast del risultato in int.

int n = (int)Long.parseLong(s, 16);

Ovviamente, dovresti farlo solo se sei sicuro che il numero sarà compreso nell'intervallo Integer.MIN_VALUE..Integer.MAX_VALUE.

Secondo la documentazione, toHexString restituisce " una rappresentazione di stringa dell'argomento intero come intero senza segno nella base 16. "

Quindi l'operazione inversa corretta è probabilmente Integer.parseUnsignedInt che è stato introdotto come parte di Java 8:

public class Main3 {
    public static void main(String[] args) {
        Integer min = Integer.MIN_VALUE;
        String minHex = Integer.toHexString(Integer.MIN_VALUE);

        System.out.println(min + " " + minHex);
        System.out.println(Integer.parseUnsignedInt(minHex, 16));
    }

Prova questo:

public class Main3 {
    public static void main(String[] args) {
        Integer min = Integer.MIN_VALUE;
        String minHex = Integer.toHexString(Integer.MIN_VALUE);

        System.out.println(min + " " + minHex);
        System.out.println(Integer.parseInt( "-" + minHex, 16));
    }

}

per ottenere questo:

-2147483648 80000000
-2147483648

Devi include un segno negativo.

Al momento non ho accesso per testarlo, ma scommetto che se invece provassi questo valore:

Integer min = Integer.MIN_VALUE + 1;

Non bombarderebbe, ma ti darebbe un numero positivo (non negativo) quando corri ParseInt(min,16).

Una stringa di bit in realtà non ha abbastanza informazioni per determinare il segno in questo contesto, quindi è necessario fornirlo. (considera il caso in cui usi min = "F". È +/- F? Se lo hai convertito in bit e hai visto 1111, e sapevi che era un byte, potresti concludere che è negativo, ma questo è un sacco di se.

Questo sembra funzionare per me:

public class Main3 {
public static void main(String[] args) {
    Integer min = Integer.MIN_VALUE;
    String minHex = Integer.toHexString(Integer.MIN_VALUE);

    System.out.println(min + " " + minHex);
    System.out.println((int)Long.parseLong(minHex, 16));
}
}

L'intero viene analizzato come " firmato long " che gestiscono un numero così grande positivo e quindi il segno viene ritrovato lanciandolo su " int " ;.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top