Java 负 int 到十六进制和返回失败
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)
怎么了?
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));
}
}
Gives
-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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
据记录,
Integer.toHexString
返回整数的字符串表示形式作为无符号值 - 而Integer.parseInt
则采用有符号 int。 如果您使用Integer.toString(value, 16)
相反,您将得到您想要的。It's documented that
Integer.toHexString
returns a string representation of the integer as an unsigned value - whileInteger.parseInt
takes a signed int. If you useInteger.toString(value, 16)
instead you'll get what you want.这是一直让我烦恼的事情。 如果使用十六进制文字初始化 int,则可以使用最大范围为
0xFFFFFF
的正值; 任何大于0x7FFFFF
的值实际上都是负值。 这对于位屏蔽和其他操作非常方便,在这些操作中您只关心位的位置,而不是它们的含义。但如果您使用 Integer.parseInt() 将字符串转换为整数,则任何大于
"0x7FFFFFFF"
的内容都会被视为错误。 他们这样做可能有充分的理由,但仍然令人沮丧。最简单的解决方法是使用 Long.parseLong() 代替,然后将结果转换为 int。
当然,只有当您确定数字在
Integer.MIN_VALUE..Integer.MAX_VALUE
范围内时,才应该这样做。This is something that's always annoyed me. If you initialize an int with a hex literal, you can use the full range of positive values up to
0xFFFFFF
; anything larger than0x7FFFFF
will really be a negative value. This is very handy for bit masking and other operations where you only care about the locations of the bits, not their meanings.But if you use Integer.parseInt() to convert a string to an integer, anything larger than
"0x7FFFFFFF"
is treated as an error. There's probably a good reason why they did it that way, but it's still frustrating.The simplest workaround is to use Long.parseLong() instead, then cast the result to int.
Of course, you should only do that if you're sure the number is going to be in the range
Integer.MIN_VALUE..Integer.MAX_VALUE
.根据文档,
toHexString
返回“整数参数的字符串表示形式,以 16 为基数的无符号整数。”因此,正确的反向操作可能是 < a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html#parseUnsignedInt-java.lang.String-int-" rel="noreferrer">
Integer.parseUnsignedInt
作为 Java 8 的一部分引入:According the the documentation,
toHexString
returns "a string representation of the integer argument as an unsigned integer in base 16. "So the correct reverse operation is probably
Integer.parseUnsignedInt
that was introduced as part of Java 8:试试这个:
}
得到这个:
Try this:
}
to get this:
您需要 包含一个负号。
我现在无法测试这个,但我敢打赌,如果你尝试这个值:
它不会爆炸,但当你运行
ParseInt(min, 16)
。位字符串实际上没有足够的信息来确定此上下文中的符号,因此您需要提供它。 (考虑一下您使用
min = "F"
的情况。这是 +/-F 吗?如果您将其转换为位并看到 1111, 您就知道这是一个字节,你可能会得出结论,它是否定的,但这是很多如果。You need to include a negative sign.
I don't have access to test this right now but I'd bet if you tried this value instead:
It wouldn't bomb, but would give you a positive number (not negative) when you ran
ParseInt(min,16)
.A string of bits doesn't really have enough info to determine sign in this context so you need to provide it. (consider the case where you use
min = "F"
. Is that +/-F? If you converted it to bits and saw 1111, and you knew it was a byte, you might conclude that it's negative, but that's a lot of ifs.这似乎对我有用:
整数被解析为处理如此大的正数的“signed long”,然后通过将其转换为“int”来找到符号。
This seem to work for me :
The integer is parsed as a "signed long" that handle such big positive number and then the sign is found back by casting it to "int".
Integer.parseInt()
接受一个有符号整数作为输入。 这意味着输入必须在“7FFFFFFF”和“-80000000”之间。 注意“80000000”前面的负号。 你想要的是Integer.parseInt("-80000000", 16)
。 如果您使用不带减号的 80000000,Java 会将其解释为正数并抛出异常,因为 int 的最大正整数为 0x7FFFFFFF。Integer.parseInt()
takes in a signed integer as it's input. This means the input has to be between "7FFFFFFF" and "-80000000". Note the negative sign before "80000000". What you want isInteger.parseInt("-80000000", 16)
. If you use 80000000 without the minus sign Java will interpret that as a positive number and throw an exception because the max positive integer for an int is 0x7FFFFFFF.