Pregunta

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

Da

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

¿Qué pasa?

¿Fue útil?

Solución

Está documentado que Integer.toHexString devuelve una representación de cadena del entero como un valor sin signo, mientras que Integer.parseInt toma un int con signo. Si usa Integer.toString(value, 16) en su lugar, obtendrá lo que desea.

Otros consejos

Esto es algo que siempre me molesta. Si inicializa un int con un literal hexadecimal, puede usar el rango completo de valores positivos hasta 0xFFFFFF; cualquier cosa mayor que 0x7FFFFF realmente será un valor negativo. Esto es muy útil para el enmascaramiento de bits y otras operaciones en las que solo le interesan las ubicaciones de los bits, no sus significados.

Pero si usa Integer.parseInt () para convertir una cadena en un entero, cualquier cosa mayor que "0x7FFFFFFF" se trata como un error. Probablemente haya una buena razón por la que lo hicieron de esa manera, pero sigue siendo frustrante.

La solución más simple es usar Long.parseLong () en su lugar, luego enviar el resultado a int.

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

Por supuesto, solo debe hacerlo si está seguro de que el número estará en el rango Integer.MIN_VALUE..Integer.MAX_VALUE.

Según la documentación, toHexString devuelve " una representación de cadena del argumento entero como un entero sin signo en la base 16. "

Entonces, la operación inversa correcta es probablemente Integer.parseUnsignedInt que se introdujo como parte de 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));
    }

Prueba esto:

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

}

para obtener esto:

-2147483648 80000000
-2147483648

Necesita incluye un signo negativo .

No tengo acceso para probar esto en este momento, pero apuesto a que si prueba este valor en su lugar:

Integer min = Integer.MIN_VALUE + 1;

No bombardearía, pero le daría un número positivo (no negativo) cuando ejecutó ParseInt(min,16).

Una cadena de bits realmente no tiene suficiente información para determinar el signo en este contexto, por lo que debe proporcionarla. (considere el caso en el que usa min = "F". ¿Es +/- F? Si lo convirtió en bits y vio 1111, y sabía que era un byte, podría concluir que es negativo, pero eso es un montón de ifs.

Esto parece funcionar para mí:

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

El entero se analiza como " firmado largo " que manejan un número positivo tan grande y luego el signo se encuentra regresándolo a " int " ;.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top