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

这是怎么回事?

4

7 回答 7

13

这是一直困扰我的事情。如果使用十六进制文字初始化 int,则可以使用最大范围内的正值0xFFFFFF;任何大于0x7FFFFF实际上都是负值。这对于位掩码和其他操作非常方便,您只关心位的位置,而不是它们的含义。

但是,如果您使用 Integer.parseInt() 将字符串转换为整数,则任何大于该值的都"0x7FFFFFFF"将被视为错误。他们这样做可能有一个很好的理由,但这仍然令人沮丧。

最简单的解决方法是改用 Long.parseLong(),然后将结果转换为 int。

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

当然,只有当您确定数字将在范围内时,您才应该这样做Integer.MIN_VALUE..Integer.MAX_VALUE

于 2009-05-10T14:05:08.620 回答
12

据记录,Integer.toHexString将整数的字符串表示形式返回为无符号值 - 而Integer.parseInt采用带符号的 int。如果你使用Integer.toString(value, 16)它,你会得到你想要的。

于 2009-05-10T12:54:28.007 回答
6

根据文档,toHexString返回“整数参数的字符串表示形式,以16 为基数的无符号整数。”

所以正确的反向操作可能Integer.parseUnsignedInt是作为 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));
    }
于 2014-12-06T14:13:09.883 回答
2

尝试这个:

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
-2147483648
于 2009-05-10T13:58:19.070 回答
1

您需要包含一个负号。

我现在无权对此进行测试,但我敢打赌,如果您尝试使用此值:

Integer min = Integer.MIN_VALUE + 1;

它不会爆炸,但会在您运行时给您一个正数(而不是负数)ParseInt(min,16)

一串位实际上没有足够的信息来确定此上下文中的符号,因此您需要提供它。(考虑使用 . 的情况min = "F"。那是 +/-F 吗?如果您将其转换为位并看到 1111,并且您知道它是一个字节,您可能会得出结论它是负数,但这是很多 ifs。

于 2009-05-10T12:20:12.703 回答
0

这似乎对我有用:

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

整数被解析为处理如此大的正数的“有符号长整数”,然后通过将其转换为“int”来找到符号。

于 2014-11-27T11:25:55.780 回答
0

Integer.parseInt()接受一个有符号整数作为输入。这意味着输入必须在“7FFFFFFF”和“-80000000”之间。注意“80000000”之前的负号。你想要的是Integer.parseInt("-80000000", 16). 如果使用不带减号的 80000000,Java 会将其解释为正数并抛出异常,因为 int 的最大正整数为 0x7FFFFFFF。

于 2022-01-27T19:56:29.180 回答