9

Why does this code throw a NumberFormatException :

String binStr = "1000000000000000000000000000000000000000000000000000000000000000";
System.out.println(binStr.length());// =  64
System.out.println(Long.parseLong(binStr, 2));
2
  • 2
    Re-reading this, it's actually a good question. Commented Feb 17, 2013 at 22:52
  • 1
    This may be an interesting question, but certainly not a good question. Commented Feb 18, 2013 at 0:12

7 Answers 7

7

1000000000000000000000000000000000000000000000000000000000000000 is larger than Long.MAX_VALUE.

See https://stackoverflow.com/a/8888969/597657

Consider using BigInteger(String val, int radix) instead.


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.

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

5 Comments

You missed what I missed when I first commented ;) It's not larger ... it doesn't exist.
String binStr = "1000000000000000000000000000000000000000000000000000000000000000"; System.out.println(binStr.length());// = 64 System.out.println(Long.parseLong(binStr, 2));
That linked answer is wrong, Java represents integers as 2's-complement internally, not sign-magnitude.
@OliCharlesworth You are right. But that's how parseInt() handles binary.
@Eng.Fouad: Well, that's true in the sense that parseInt/parseLong expect negative numbers to be represented with a "-" character. But that's got nothing to do with the internal representation!
5

Because it's out of range. 1000...000 is 263, but Long only goes up to 263 - 1.

2 Comments

You missed what I missed when I first commented ;) It's not larger, it doesn't exist.
So after all our discussion, it should be Long.MIN_VALUE from the bit pattern, but parseLong doesn't like that. Learn something new every day :)
4

This is the same for all of Long, Integer, Short and Byte. I'll explain with a Byte example because it's readable:

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:

Parses the string argument as a signed long in the radix specified by the second argument. 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 '-' ('\u002D') to indicate a negative value or an ASCII plus sign '+' ('\u002B') to indicate a positive value. The resulting long value is returned.

In order to get MAX_VALUE we need:

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

Comments

3

This is because Long.parseLong cannot parse two's complement representation. The only way to parse two's complement binary string representation in Java SE is BigInteger:

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

this gives expected -9223372036854775808result

Comments

2

Largest long value is actually:

0111111111111111111111111111111111111111111111111111111111111111b = 9223372036854775807

Comments

0

This is the largest possible long (9223372036854775807 = 2 exp 63 - 1) in binary format. Note the L at the end of the last digit.

 long largestLong = 0B0111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111L;

Comments

-1

Actually, this is works for me:

String bitStr = "-1000000000000000000000000000000000000000000000000000000000000000";
System.out.println(Long.parseLong(bitStr, 2));

Here is a thing: inside Long.parseLong() code logic is looking for explicit sign first. And respectively to the sign, different limits are used (Long.MAX_VALUE for positive, and Long.MIN_VALUE for negative binary literals). Probably it would be better if this logic looked up first to the eldest bit (0 for positive and 1 for negative numbers) the sign

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.