为什么这段代码会抛出NumberFormatException
:
String binStr = "1000000000000000000000000000000000000000000000000000000000000000";
System.out.println(binStr.length());// = 64
System.out.println(Long.parseLong(binStr, 2));
为什么这段代码会抛出NumberFormatException
:
String binStr = "1000000000000000000000000000000000000000000000000000000000000000";
System.out.println(binStr.length());// = 64
System.out.println(Long.parseLong(binStr, 2));
1000000000000000000000000000000000000000000000000000000000000000
大于Long.MAX_VALUE
。
请参阅https://stackoverflow.com/a/8888969/597657
考虑BigInteger(String val, int radix)
改用。
编辑:
好的,这对我来说是新的。似乎Integer.parseInt(binaryIntegerString, 2)
并将Long.parseLong(binaryLongString, 2)
二进制解析为符号幅度而不是2的补码。
因为超出范围。 1000...000
是 2 63,但Long
只上升到 2 63 - 1。
这对于所有Long
、Integer
和都是相同Short
的Byte
。我会用一个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
最大的 long 值实际上是:
0111111111111111111111111111111111111111111111111111111111111111b = 9223372036854775807
这是因为 Long.parseLong 无法解析二进制补码表示。在 Java SE 中解析二进制补码表示的唯一方法是 BigInteger:
long l = new BigInteger("1000000000000000000000000000000000000000000000000000000000000000", 2).longValue()
这给出了预期的 -9223372036854775808result
这是二进制格式的最大可能长 (9223372036854775807 = 2 exp 63 - 1)。请注意最后一位数字末尾的 L。
long largestLong = 0B0111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111L;
实际上,这对我有用:
String bitStr = "-1000000000000000000000000000000000000000000000000000000000000000";
System.out.println(Long.parseLong(bitStr, 2));
这是一件事:在 Long.parseLong() 代码逻辑中首先寻找显式符号。并且分别对符号使用不同的限制(Long.MAX_VALUE 表示正数,Long.MIN_VALUE 表示负二进制文字)。如果这个逻辑首先查找最高位(0 表示正数,1 表示负数)符号可能会更好