Java Integer.parseInt () for 32-bit binary string string numbers NumberFormatException

Is this api java error?

int i = 0xD3951892; System.out.println(i); // -745203566 String binString = Integer.toBinaryString(i); int radix = 2; int j = Integer.valueOf(binString, radix ); Assertions.assertThat(j).isEqualTo(i); 

I expect this to be true without any questions. But he throws an exception below:

 java.lang.NumberFormatException: For input string: "11010011100101010001100010010010" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.lang.Integer.parseInt(Integer.java:495) at java.lang.Integer.valueOf(Integer.java:556) at com.zhugw.temp.IntegerTest.test_valueof_binary_string(IntegerTest.java:14) 

So, if I have a binary string, for example. 11010011100101010001100010010010, How can I get its decimal number (-745203566) in Java? DIY? Write a code to implement the equation below?

enter image description here

+6
source share
2 answers

Integer.valueOf(String, int radix) and Integer.parseInt(String, int radix) will only analyze numbers from -2,147,483,648 to 2,147,483,647, that is, the values โ€‹โ€‹of 32-bit signed integers.

These functions cannot interpret two complement numbers for binary ( radix = 2 ), because the transmitted string can be of any length, and therefore the leading 1 can be part of a number or a sign bit. I think the Java developers decided that the most logical way is to never accept two additions, and not assume that the 32nd bit is a signed bit.

They read your binary input string as unsigned 3,549,763,730 (more than max int value). To read a negative value, you must give a positive binary number with a - in front. For example, for -5 :

 Integer.parseInt("1011", 2); // 11 // Even if you extended the 1s to try and make two complement of 5, // it would always read it as a positive binary value Integer.parseInt("-101", 2); // -5, this is right 

Solutions:

I suggest, firstly, that if you can save it as a positive number with additional information about the sign yourself (for example, the - symbol), do it. For instance:

 String binString; if(i < 0) binString = "-" + Integer.toBinaryString(-i); else // positive i binString = Integer.toBinaryString(i); 

If you need to use signed binary strings to accept a negative binary number of two additions (like a string) and parse it into int, I suggest you take two additions manually, convert them to int, and then correct the sign. Recall that two additions = one addition + 1, and one addition just reverses each bit.

As an example implementation:

 String binString = "11010011100101010001100010010010"; StringBuilder onesComplementBuilder = new StringBuilder(); for(char bit : binString.toCharArray()) { // if bit is '0', append a 1. if bit is '1', append a 0. onesComplementBuilder.append((bit == '0') ? 1 : 0); } String onesComplement = onesComplementBuilder.toString(); System.out.println(onesComplement); // should be the NOT of binString int converted = Integer.valueOf(onesComplement, 2); // two complement = one complement + 1. This is the positive value // of our original binary string, so make it negative again. int value = -(converted + 1); 

You can also write your own version of Integer.parseInt for 32-bit binary numbers with two additions. This, of course, assumes that you are not using Java 8 and cannot simply use Integer.parseUnsignedInt , as @llogiq pointed out when I introduced this.

EDIT: First you can use Long.parseLong(String, 2) , and then calculate two additions (and mask it by 0xFFFFFFFF), and then lower long to int . Faster to write, possibly faster code.

+8
source

The API docs for Integer.toBinaryString(..) explicitly state:

The value of the argument can be recovered from the returned string s by calling Integer.parseUnsignedInt(s, 8) .

(as in Java 8u25) I think this is a documentation error and it should read Integer.parseUnsignedInt(s, 2) . Pay attention to Unsigned . This is because the output of toBinaryString will contain a sign bit.

Edit: note that even if it looks like it will give an unsigned value, it is not. This is because Java really has no concept of unsigned values, only a few static methods for working with int, as if they were unsigned.

+4
source

All Articles