Java 8: Why can't I parse this binary string i

2019-02-20 03:27发布

Long story short, I was messing around with some basic genetic algorithm stuff in Java. I was using a long to store my genes, but I was using binary strings for readability while debugging. I came across an odd situation where I couldn't parse some binary strings that start with a 1 (I don't know if this is always the case, but it seems to be consistent with strings of 64 characters in length).

I was able to replicate this with the following example:

String binaryString = Long.toBinaryString(Long.MIN_VALUE);
long smallestLongPossibleInJava = Long.parseLong(binaryString, 2);

Which will throw and produce the following stacktrace:

Exception in thread "main" java.lang.NumberFormatException: For input string: "1000000000000000000000000000000000000000000000000000000000000000"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Long.parseLong(Long.java:592)
    at com.company.Main.main(Main.java:25)

Given that I have a correctly formatted binary string of sixty four characters in length, why can't I parse some strings to a long? Most of the time, my strings are randomly generated, but in the instance above this should work (seeing as Long.MIN_VALUE is definitely a valid long in Java).

1条回答
爷的心禁止访问
2楼-- · 2019-02-20 04:09

Quoting Long.toBinaryString(i) Javadoc (emphasis mine):

Returns a string representation of the long argument as an unsigned integer in base 2.

And quoting Long.parseLong(s, radix) (emphasis mine):

Parses the string argument as a signed long in the radix specified by the second argument.

The problem comes from the fact that toBinaryString returns a unsigned value whereas parseLong expects a signed value.

You should use Long.parseUnsignedLong(s, radix) instead:

String binaryString = Long.toBinaryString(Long.MIN_VALUE);
long smallestLongPossibleInJava = Long.parseUnsignedLong(binaryString, 2);

Note that this is actually explicitely said in toBinaryString Javadoc:

The value of the argument can be recovered from the returned string s by calling Long.parseUnsignedLong(s, 2).

查看更多
登录 后发表回答