1

I was testing out the bitwise not operator in Java. I printed out the result of ~1 in binary, and it returned "11111111111111111111111111111110" which apparently evaluates to -2.

I know that you have to add 1 to this to get -1 and that the leftmost bit just shows whether the number is positive or negative, but what I don't understand is why a binary number that large and with that many 1s evaluates to just -2.

Karol Dowbecki
  • 43,645
  • 9
  • 78
  • 111
  • https://en.wikipedia.org/wiki/Two%27s_complement and https://en.wikipedia.org/wiki/Ones%27_complement – jhamon Dec 06 '18 at 15:41
  • Consider that if you added 2 to it, the carry would go through all of those ones and make them zero. x+2=0 therefore x=-2 – harold Dec 06 '18 at 17:03

3 Answers3

2

11111111111111111111111111111110 is raw bit representation. Java uses two's complement for signed value representation where the first bit, if set, denotes a negative number.

This is well explained by Conversion from Two's Complement:

Use the number 0xFFFFFFFF as an example. In binary, that is:

1111 1111 1111 1111 1111 1111 1111 1111

What can we say about this number? It's first (leftmost) bit is 1, which means that this represents a number that is negative. That's just the way that things are in two's complement: a leading 1 means the number is negative, a leading 0 means the number is 0 or positive.

To see what this number is a negative of, we reverse the sign of this number. But how to do that? The class notes say (on 3.17) that to reverse the sign you simply invert the bits (0 goes to 1, and 1 to 0) and add one to the resulting number.

The inversion of that binary number is, obviously:

0000 0000 0000 0000 0000 0000 0000 0000

Then we add one.

0000 0000 0000 0000 0000 0000 0000 0001

So the negative of 0xFFFFFFFF is 0x00000001, more commonly known as 1. So 0xFFFFFFFF is -1.

Above illustrates why the negative in two's complement (as in reverse bits and add one) of 0xFFFFFFFF is 1 which means that by itself 0xFFFFFFFF means -1. In the same way your value of 0xFFFFFFFE has a negative of 2 so by itself 0xFFFFFFFE means -2 in two's complement.

Karol Dowbecki
  • 43,645
  • 9
  • 78
  • 111
1

Another way of thinking about this, is that in a 32 bit signed integers the leftmost digit represents one of two numbers:

0000000000000000000000000000000 represents 0
1000000000000000000000000000000 represents -2147483648

by definition. Everything else is an addition (added to) to this, so:

BINARY REPRESENTATION                      INT REPRESENTATION
1000000000000000000000000000000 plus       -2147483648 plus
0111111111111111111111111111110 equals      2147483646 equals
1111111111111111111111111111110                     -2

It would be helpful to think of the left-most (leading) bit as defining where you start counting from:

  • if the leftmost bit is 0, you start counting from 0
  • if the leftmost bit is 1, you start counting from -2147483648

The remaining 31 bits to the right of it define the integer value itself by making up a number (up to 2147483647 for 111 1111 1111 1111 1111 1111 1111) that is added to the starting point.


Effectively then, signed integers wrap around. THey count up to a max value of about 2 billion, then instantly flip to -2 billion and count up to 0 again:

0111111111111111111111111111111 is 2147483647. If you add one to this you get: 1000000000000000000000000000000 which is either 2147483648 as an unsigned integer or -2147483648, and it is this way by definition. As you keep adding to any integer it approaches: 1111111111111111111111111111111 which is -1 as a signed integer, or 4294967295 as an unsigned

Ultimately, you should appreciate and understand that signed integers wrap around if you keep adding to them, but they instantly jump from the max positive to the min negative value in the middle:

0, 1, ... 2147483646, 2147483647, -2147483648, -2147483647, ... -2, -1

This is why your '11111111111111111111111111111110' is -2, as it's one less than the maximum binary representation (which represents -1 in signed int space)

Caius Jard
  • 72,509
  • 5
  • 49
  • 80
0

It's two's complement. If you want to convert a number to TC (given 2 as an example):

  1. write it as a binary (let's assume it's just 8 bits for a shorter representation)

    00000010
    
  2. negate all bits

    11111101
    
  3. add 1

    11111110
    

That's basically why 2 looks like that.

g-t
  • 1,455
  • 12
  • 17