15
int a = Integer.MIN_VALUE;
int b = -a;
System.out.println("a = "+a + " | b = "+b);

Result :

a = -2147483648 | b = -2147483648

I was expecting b to be a positive number.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
aviad
  • 8,229
  • 9
  • 50
  • 98
  • 3
    because the max positive number is one smaller. it takes 0 in account, and has as much positive as negative numbers – Stultuske May 15 '17 at 16:54
  • 4
    Max value for an integer is 2147483647, so it loops back round to min value. It should work if you add 1 to `a` bevore assigning value to `b`. – AntonH May 15 '17 at 16:55
  • 8
    This is a quirk of twos-complement, basically. Consider the `byte` type, with values from -128 to 127... if you have a byte `x` with a value of -128, what would the value of `-x` be? – Jon Skeet May 15 '17 at 16:55
  • 4
    Every programmer must know two's-complement arithmetic. Also, the format and ranges of the numeric types are covered IN THE DOCUMENTATION. – Lew Bloch May 15 '17 at 17:07
  • 2
    If you were expecting `b` to be a positive number, *what* positive number were you expecting, and *why* were you expecting that, given that `Integer.MAX_VALUE` is 2147483647? – Andreas May 15 '17 at 17:13
  • And we don't have a dup for this? Where is Jarrod when we could for once need his input :-) – GhostCat May 15 '17 at 17:19
  • 1
    This code prints those negative numbers because the `System.out.println` is intended for printing the argument and does it's job well :) – Džuris May 15 '17 at 20:20

4 Answers4

20

Changing the sign of Integer.MIN_VALUE produces an overflow; you're seeing the result of that.

gyre
  • 16,369
  • 3
  • 37
  • 47
Andres
  • 10,561
  • 4
  • 45
  • 63
16

If you have ever done something like this:

int a = Integer.MAX_VALUE;
a++;
System.out.println(a);

You will know that when something exceeds the data type's max value, it loops back to its min value. And when it is less than the min value, it loops back to the max value.

The same thing happens here.

Negating the min value of int would mathematically give us 2147483648, but since that is one larger than the max value. It loops back to the min value again, which is -2147483648.

Fun fact: negation is basically switching every bit from 0 to 1 and 1 to 0, then adding one. Try doing this to 10000000000000000000000000000000 which is what int's min value looks like in binary.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
5

For the underlying binary explanation, it is because signed Integers are stored with Two's complement.

So, the most negative number in binary is 1000 0000. To inverse the sign, you flip all the bits, and add one so..

1000 0000 => 0111 1111 + 1 = 1000 0000

And you're back where you started!

As in the example above, the signed range of a Byte (8 bits) is −128 to 127, so -(-128) is 128, which is 1 over 127, so it overflows back to -128.

And as for why use Two's complement? 1 - 1 becomes 1 + (-1) or 0001 + 1111 = 0000. So by storing negative numbers in Two's complement, subtraction is done by just takes the Two's complement of the second number and just adding them together. (Which is much more efficient for the machine than adding a subtraction circuit to the the Arithmetic-Logic Unit (ALU); As it already has the bit-wise not and addition to do twos complement).

Tezra
  • 8,463
  • 3
  • 31
  • 68
1

Usually when we try to assign a value to an int type which is more than the max value of int type it loopbacks again starts from min value of int, e.g.

2147483648 -will become-> -2147483648
2147483649 -will become-> -2147483647
2147483650 -will become-> -2147483646

After first statement value of a is -2147483648

And when you are doing int b = -a; usually b should have

b = -a --> -(-2147483648) --> 2147483648

But max positive value of int is 2147483647 and 2147483648 is one larger than 2147483647 it will loop back by 1 and become -2147483648.

Naresh Joshi
  • 4,188
  • 35
  • 45