Java,Long.parse二进制字符串

为什么这段代码会抛出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。

这对于LongIntegerShortByte 。 我将用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 

无论提供什么基数,数字都是无符号解释的。 如果你想要一个负值,你必须在String的开头有减号。 JavaDoc说:

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

为了获得MAX_VALUE我们需要:

 String max = "1111111"; // 7 binary digits, +127 // or String max2 = "+1111111"; // 7 binary digits, +127 

最大的长值实际上是:

 0111111111111111111111111111111111111111111111111111111111111111b = 9223372036854775807 

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

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

这给了预期-9223372036854775808结果

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

  long largestLong = 0B0111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111L;