Java – Convert negative binary to Integer

Review the following Java example to convert a negative integer in binary string back to an integer type.


  String binary = Integer.toBinaryString(-1);   // convert -1 to binary
                                                // 11111111 11111111 11111111 11111111 (two's complement)
  int number = Integer.parseInt(binary, 2);     // convert negative binary back to integer
  System.out.println(number);                   // output ??

The result is NumberFormatException!


Exception in thread "main" java.lang.NumberFormatException: For input string: "11111111111111111111111111111111" under radix 2
	at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68)
	at java.base/java.lang.Integer.parseInt(Integer.java:652)
	at com.mkyong.crypto.bytes.Byte2.main(Byte2.java:17)

The NumberFormatException is due to overflow, the string 11111111111111111111111111111111 (length of 32) are unable to fit into the 32 bits int type?

Note
Integer has values from -2^31 to 2^31-1 , not 2^32-1.

1. Integer Overflow?

In Java, the int is a 32 bits two’s complement integer, the first leftmost bit or most significant bit is denote the sign of the numbers, 0 is positive, 1 is negative.


{1}1111111 11111111 11111111 11111111 = {1} = most significant bit, denote positive or negative

Since the leftmost bit is reserved for the sign of the numbers, the Java int 32 bits only has values from -2^31 (-2,147,483,648) to 2^31-1 (2,147,483,647).


  System.out.println(Integer.MIN_VALUE);  // -2,147,483,648 , -2^31
  System.out.println(Integer.MAX_VALUE);  // 2,147,483,647 , 2^31-1

Review the binary string again, that is a full 32 bits, 2^32-1 (4,294,967,295). The int type is unable to handle such a large number, and Java doesn’t support unsigned int.


11111111 11111111 11111111 11111111

2. Long

To solve it, we can use long, 64 bits two’s complement integer, has values from -2^63 to 2^63-1.


  String binary = Integer.toBinaryString(-1);

  //int number = Integer.parseInt(binary, 2);

  long l = Long.parseLong(binary, 2);                 // 11111111 11111111 11111111 11111111
  int number = (int) l;

  System.out.println(number);                         // -1

3. Java 8

For Java 8, it introduced new APIs to support unsigned operations, try Integer.parseUnsignedInt().


  String binary = Integer.toBinaryString(-1);

  //int number = Integer.parseInt(binary, 2);
  int number = Integer.parseUnsignedInt(binary, 2);

  System.out.println(number);                         // -1

References

Image

mkyong

Founder of Mkyong.com, passionate Java and open-source technologies. If you enjoy my tutorials, consider making a donation to these charities.

2 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Schmichael
5 years ago

“Review the binary string again, that is a full 32 bits, 2^32-1 (4,294,967,295). The int type is unable to handle such a large number, and Java doesn’t support unsigned int.”

Even with the full 32 bits, why wouldn’t Java treat the first bit as the sign bit? Treating as such will give us a consistent answer as you mentioned earlier, which I’ll quote below.

“Since the leftmost bit is reserved for the sign of the numbers, the Java int 32 bits only has values from -2^31 (-2,147,483,648) to 2^31-1 (2,147,483,647).”

I believe your explanation was not consistent.

The problem I got stuck on was solved because of your post but I don’t find it consistent in your reasoning.