9

为什么这段代码会抛出NumberFormatException

String binStr = "1000000000000000000000000000000000000000000000000000000000000000";
System.out.println(binStr.length());// =  64
System.out.println(Long.parseLong(binStr, 2));
4

7 回答 7

7

1000000000000000000000000000000000000000000000000000000000000000大于Long.MAX_VALUE

请参阅https://stackoverflow.com/a/8888969/597657

考虑BigInteger(String val, int radix)改用。


编辑:

好的,这对我来说是新的。似乎Integer.parseInt(binaryIntegerString, 2)并将Long.parseLong(binaryLongString, 2)二进制解析为符号幅度而不是2的补码。

于 2013-02-17T22:40:23.137 回答
5

因为超出范围。 1000...000是 2 63,但Long只上升到 2 63 - 1。

于 2013-02-17T22:40:23.177 回答
4

这对于所有LongInteger和都是相同ShortByte。我会用一个Byte例子来解释,因为它是可读的:

System.out.println(Byte.MIN_VALUE); // -128
System.out.println(Byte.MAX_VALUE); // 127
String positive =  "1000000"; // 8 binary digits, +128 
String negative = "-1000000"; // 8 binary digits, -128
String plus     = "+1000000"; // 8 binary digits, +128
Byte.parseByte(positive, 2); //will fail because it's bigger than Byte.MAX_VALUE 
Byte.parseByte(negative, 2); //won't fail. It will return Byte.MIN_VALUE
Byte.parseByte(plus, 2);     //will fail because its bigger than Byte.MAX_VALUE

无论提供什么基数,这些数字都被解释为无符号数。如果你想要一个负值,你必须在字符串的开头加上减号。JavaDoc说:

将字符串参数解析为第二个参数指定的基数中的有符号长整数。字符串中的字符必须都是指定基数的数字(由是否Character.digit(char, int)返回非负值来决定),除了第一个字符可以是ASCII减号'-' ('\u002D')表示负值或ASCII加号'+' ('\u002B')表示正值. 返回结果的 long 值。

为了得到MAX_VALUE我们需要:

String max  =  "1111111"; // 7 binary digits, +127 
// or
String max2 = "+1111111"; // 7 binary digits, +127 
于 2013-02-17T23:49:15.167 回答
2

最大的 long 值实际上是:

0111111111111111111111111111111111111111111111111111111111111111b = 9223372036854775807
于 2013-02-17T22:44:00.737 回答
2

这是因为 Long.parseLong 无法解析二进制补码表示。在 Java SE 中解析二进制补码表示的唯一方法是 BigInteger:

long l = new BigInteger("1000000000000000000000000000000000000000000000000000000000000000", 2).longValue()

这给出了预期的 -9223372036854775808result

于 2013-08-29T11:06:04.733 回答
0

这是二进制格式的最大可能长 (9223372036854775807 = 2 exp 63 - 1)。请注意最后一位数字末尾的 L。

 long largestLong = 0B0111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111L;
于 2017-01-05T23:36:05.117 回答
-1

实际上,这对我有用:

String bitStr = "-1000000000000000000000000000000000000000000000000000000000000000";
System.out.println(Long.parseLong(bitStr, 2));

这是一件事:在 Long.parseLong() 代码逻辑中首先寻找显式符号。并且分别对符号使用不同的限制(Long.MAX_VALUE 表示正数,Long.MIN_VALUE 表示负二进制文字)。如果这个逻辑首先查找最高位(0 表示正数,1 表示负数)符号可能会更好

于 2021-06-21T18:26:28.417 回答