1

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).

2
  • 2
    If the first bit is a one then this denotes that the number is negative . So this is likely why you will struggle with strings starting with a 1, parseLong is signed and toBinaryString is unsigned. Commented Nov 5, 2015 at 16:48
  • 1
    If you find yourself wanting to go beyond 64 bits, java.util.BitSet may come in handy. Commented Nov 5, 2015 at 19:19

1 Answer 1

15

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).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.