Vivin
Vivin

Reputation: 1367

Why Integer.toBinaryString returns 32 bits if the argument is negative?

I was just messing around the Integer.toBinaryString(int) method.

When I pass a positive number say 7, it outputs 111 but when I pass negative 7, it outputs 11111111111111111111111111111001. I understand that Java uses 2's complement to represent negative numbers, but why 32 bits (I also know that an int is 32 bits long but doesn't fit in the answer)?

Upvotes: 3

Views: 2464

Answers (3)

Noah Herron
Noah Herron

Reputation: 640

Ok so I did some digging...

I wrote up a little program probably close to what you did.

public class IntTest {
    public static void main(String[] args){
        int a = 7;
        int b = -7;
        System.out.println(Integer.toBinaryString(a));
        System.out.println(Integer.toBinaryString(b));
    }
}

My output:

111

11111111111111111111111111111001

So 111 is the same if it had 29 "0"s in front of it. That is just wasted space and time.

If we follow the instructions for twos compliment from this guy here you can see that what we must do is flip the bits ( zeros become ones and ones become zeros ) then we add 1 to the result.

So 0000 0000 0000 0000 0000 0000 0000 0111 becomes 1111 1111 1111 1111 1111 1111 1111 1001

The ones can not be thrown out because they are significant in the twos compliment representation. This is why you have 32 bits in the second case.

Hope this helps! -- Code on!!!

Upvotes: 4

John Humphreys
John Humphreys

Reputation: 39354

It outputs the smallest number it can, stripping leading zeroes. In the case of a negative number, the first bit of the 32 bits is a sign bit (i.e. -1 is 1, 30 zeros, and another 1). So, since it has to output the sign bit (it's significant), it outputs all 32 bits.

Here's a cool semi-relevant example of using the sign bit and the unsigned shift operator :). If you do:

int x = {positive_value};
int y = {other_positive_value};
int avg = (x + y) >>> 1;

The x and y integers can both use the first 31 bits since the 32nd bit is the sign. This way, if they overflow, they overflow into the sign bit and make the value negative. The >>> is an unsigned shift operator which shifts the value back one bit to the right which is effectively a divide by two and floor operation, which gives a proper average.

If you, on the other hand, had done:

int x = {value};
int y = {other_value};
int avg = (x + y) / 2;

And you had gotten an overflow, you would end up with the wrong result as you'd be dividing a negative value by 2.

Upvotes: 2

Elliott Frisch
Elliott Frisch

Reputation: 201527

Because Java ints are signed 32-bit. If you use a negative number the first bit must be 1.

System.out.println(Integer.toBinaryString(0));
System.out.println(Integer.toBinaryString(Integer.MAX_VALUE)); // 31 bits
System.out.println(Integer.toBinaryString(Integer.MAX_VALUE - 1)); // 31 bits
System.out.println(Integer.toBinaryString(Integer.MAX_VALUE + 1)); // 32 bits
System.out.println(Integer.SIZE);

Output is

0
1111111111111111111111111111111
1111111111111111111111111111110
10000000000000000000000000000000
32

Note that Integer.MAX_VALUE + 1 is Integer.MIN_VALUE (and it has an extra bit).

Upvotes: 2

Related Questions