简体   繁体   English

Java,Long.parse二进制字符串

[英]Java, Long.parse binary String

Why does this code throw a NumberFormatException : 为什么这段代码会抛出NumberFormatException

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

1000000000000000000000000000000000000000000000000000000000000000 is larger than Long.MAX_VALUE . 1000000000000000000000000000000000000000000000000000000000000000大于 Long.MAX_VALUE

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

Consider using BigInteger(String val, int radix) instead. 请考虑使用BigInteger(String val, int radix)


EDIT: 编辑:

OK, this is new for me. 好的,这对我来说是新的。 It appears that Integer.parseInt(binaryIntegerString, 2) and Long.parseLong(binaryLongString, 2) parse binary as sign-magnitude not as a 2's-complement. 似乎Integer.parseInt(binaryIntegerString, 2)Long.parseLong(binaryLongString, 2)二进制解析为符号幅度而不是2的补码。

Because it's out of range. 因为它超出了范围。 1000...000 is 2 63 , but Long only goes up to 2 63 - 1. 1000...000是2 63 ,但Long只上升到2 63 - 1。

This is the same for all of Long , Integer , Short and Byte . 对于LongIntegerShortByte I'll explain with a Byte example because it's readable: 我将用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

The digits are interpreted unsigned, no matter what radix is provided. 无论提供什么基数,数字都是无符号解释的。 If you want a negative value, you have to have the minus sign at the beginning of the String. 如果你想要一个负值,你必须在字符串的开头有减号。 JavaDoc says: JavaDoc说:

Parses the string argument as a signed long in the radix specified by the second argument. 将字符串参数解析为第二个参数指定的基数中的有符号long。 The characters in the string must all be digits of the specified radix (as determined by whether Character.digit(char, int) returns a nonnegative value), except that the first character may be an ASCII minus sign '-' ('\-') to indicate a negative value or an ASCII plus sign '+' ('\+') to indicate a positive value. 字符串中的字符必须都是指定基数的数字(由Character.digit(char, int)返回非负值确定),除了第一个字符可能是ASCII减号'-' ('\-')表示负值或ASCII加号'+' ('\+')表示正值。 The resulting long value is returned. 返回结果长值。

In order to get MAX_VALUE we need: 为了获得MAX_VALUE我们需要:

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

最大的长值实际上是:

0111111111111111111111111111111111111111111111111111111111111111b = 9223372036854775807

This is because Long.parseLong cannot parse two's complement representation. 这是因为Long.parseLong无法解析二进制补码表示。 The only way to parse two's complement binary string representation in Java SE is BigInteger: 在Java SE中解析二进制补码二进制字符串表示的唯一方法是BigInteger:

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

this gives expected -9223372036854775808result 这给了预期-9223372036854775808结果

This is the largest possible long (9223372036854775807 = 2 exp 63 - 1) in binary format. 这是二进制格式中最大的可能长度(9223372036854775807 = 2 exp 63-1)。 Note the L at the end of the last digit. 注意最后一位数末尾的L.

 long largestLong = 0B0111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111L;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM