Pergunta

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)

Whats up?

Foi útil?

Solução

É documentado que Integer.toHexString retorna uma representação de string do número inteiro como um valor não assinado - enquanto Integer.parseInt leva um int assinado. Se você usar Integer.toString(value, 16) vez você vai conseguir o que deseja.

Outras dicas

Isso é algo que sempre me incomodou. Se você inicializar um int com um literal hexadecimal, você pode usar toda a gama de valores positivos até 0xFFFFFF; qualquer coisa maior que 0x7FFFFF realmente vai ser um valor negativo. Isto é muito útil para mascarar bit e outras operações onde você só se preocupam com o locais dos bits, não seus significados.

Mas se você usar Integer.parseInt () para converter uma string para um inteiro, qualquer coisa maior do que "0x7FFFFFFF" é tratado como um erro. Há provavelmente uma boa razão por que eles fizeram isso dessa forma, mas ainda é frustrante.

A solução mais simples é usar Long.parseLong () em vez disso, em seguida, converter o resultado para int.

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

É claro, você só deve fazer isso se tiver certeza o número vai ser na Integer.MIN_VALUE..Integer.MAX_VALUE gama.

De acordo com a documentação, toHexString retornos "uma representação de string do argumento inteiro como um não assinado inteiro em base 16."

Assim, a operação inversa correta é provavelmente Integer.parseUnsignedInt que foi introduzido 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));
    }

Tente isto:

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 obter este:

-2147483648 80000000
-2147483648

Você precisa incluem sinal negativo .

Eu não tenho acesso a testar isso agora, mas eu aposto que se você tentou este valor em vez disso:

Integer min = Integer.MIN_VALUE + 1;

Não seria bombardear, mas iria dar-lhe um número positivo (não negativo) quando executou ParseInt(min,16).

A string de bits realmente não tem informação suficiente para determinar sinal neste contexto de modo que você precisa para fornecê-la. (Considere o caso em que você usa min = "F". É isso +/- F? Se você converteu-o em pedaços e viu 1111, e você sabia que era um byte, você pode concluir que ele é negativo, mas que de um monte de ifs.

Este parece trabalhar para mim:

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

O inteiro é analisado como um "assinado longa" que lidar com esse número positivo grande e, em seguida, o sinal é encontrado de volta, lançando-a "int".

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top