Question

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));
    }
}

Donne

-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)

Quoi de neuf?

Était-ce utile?

La solution

Il est documenté que Integer.toHexString retourne une représentation sous forme de chaîne de l'entier sous forme de valeur non signée - tandis que Integer.parseInt prend un entier signé. Si vous utilisez Integer.toString(value, 16) à la place, vous obtiendrez ce que vous voulez.

Autres conseils

C'est quelque chose qui m'a toujours agacé. Si vous initialisez un int avec un littéral hexadécimal, vous pouvez utiliser toute la plage de valeurs positives allant jusqu'à 0xFFFFFF; tout ce qui est plus grand que 0x7FFFFF sera vraiment une valeur négative. C’est très pratique pour le masquage de bits et d’autres opérations dans lesquelles vous ne vous souciez que des emplacements des bits, pas de leur signification.

Mais si vous utilisez Integer.parseInt () pour convertir une chaîne en entier, toute valeur supérieure à "0x7FFFFFFF" est considérée comme une erreur. Il y a probablement une bonne raison pour laquelle ils l'ont fait de cette façon, mais c'est toujours frustrant.

La solution la plus simple consiste à utiliser Long.parseLong () à la place, puis de convertir le résultat en int.

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

Bien sûr, vous ne devriez le faire que si vous êtes sûr que le nombre va se situer dans la plage Integer.MIN_VALUE..Integer.MAX_VALUE.

Selon la documentation, toHexString renvoie & "; une représentation sous forme de chaîne de l'argument entier sous la forme d'un entier unsigned en base 16. &";

Donc, l'opération inverse correcte est probablement Integer.parseUnsignedInt introduit dans 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));
    }

Essayez ceci:

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));
    }

}

pour obtenir ceci:

-2147483648 80000000
-2147483648

Vous devez inclure un signe négatif .

Je n'ai pas accès à ce test pour le moment, mais je parierais que si vous essayiez cette valeur à la place:

Integer min = Integer.MIN_VALUE + 1;

Cela ne bombarderait pas, mais vous donnerait un nombre positif (non négatif) lorsque vous courriez ParseInt(min,16).

Une chaîne de bits n'a pas vraiment assez d'informations pour déterminer le signe dans ce contexte, vous devez donc le fournir. (Pensez au cas où vous utilisez min = "F". Est-ce +/- F? Si vous le convertissez en bits et que vous avez vu 1111, et vous saviez que c'était un octet, vous pourriez en déduire que c'est négatif, mais ça fait beaucoup de si.

Cela semble fonctionner pour moi:

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'entier est analysé comme un & "long signé &"; que le nombre positif est élevé et que le signe est retrouvé en le lançant en & "int &";

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top