10

Consider the below java code.

Integer value = Integer.MIN_VALUE;
System.out.println(value);

value = -value;
System.out.println(value);

Output

-2147483648
-2147483648

How the negative value of Integer.MIN_VALUE value results the same value?

However the result can't be 2147483648 because the maximum value of Integer in java is 2147483647.

But want to know why -2147483648? What kind of bit-wise operations are happening internally?

Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
Nageswaran
  • 7,481
  • 14
  • 55
  • 74
  • For the reopen voters, [this](http://stackoverflow.com/a/17256127/438154) answer in the duplicate explains the negation of `Integer.MIN_VALUE`. Duplicates aren't about the questions being the same, they are about _This question already has an answer here_, as the label states. – Sotirios Delimanolis Jul 21 '15 at 14:47

2 Answers2

15

When you negate -2147483648, it resolves to 2147483648, which exceeds the Integer.MAX_VALUE with 1. Then the value overflows to Integer.MIN_VALUE again.

From the JLS:

The integral types are byte, short, int, and long, whose values are 8-bit, 16-bit, 32-bit and 64-bit signed two's-complement integers.

So, every unary operation done on an integer will actually be applied on the two's complement representation of the number. When the Integer.MAX_VALUE is reached it will consist of a leading 0 and 31 1 bits. Adding 1 would make it a number with a leading 1 and 31 trailing 0s, which is actually the two's complement representation of Integer.MIN_VALUE.

Konstantin Yovkov
  • 62,134
  • 8
  • 100
  • 147
  • 2
    `When the Integer.MAX_VALUE is reached it will consist of 32 1 bits. Adding 1 would make it 33-bit number with a leading 1 and trailing 0s.` - you got it a bit wrong. Integer.MAX_VALUE is a 0 followed by 31 1 bits. Adding one to it results in 1 followed by 31 0 bits, which is the twos complement representation of Integer.MIN_VALUE – Eran Jul 21 '15 at 13:49
14

What kind of bit-wise operations are happening internally?

Java uses two's complement representation of signed numbers. Therefore, the change of sign operation, consists of two steps:

  1. Inverting the bits of the original value, and
  2. Adding 1 to the result.

2147483648's representation is shown below:

10000000000000000000000000000000

Inverting it produces

01111111111111111111111111111111

Adding 1 makes it the same number again, i.e.

10000000000000000000000000000000

due to integer overflow.

Force444
  • 3,321
  • 9
  • 39
  • 77
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 1
    Why do you restrict this to positive numbers as input? – laune Jul 21 '15 at 13:32
  • @laune I see what you mean. Edited to avoid the confusion. – Sergey Kalinichenko Jul 21 '15 at 13:39
  • @Codebender The result of the addition of `1` is greater than what the highest positive value the `int` can hold, so that's an overflow. – Sergey Kalinichenko Jul 21 '15 at 13:43
  • Another nit: Technically, adding 1 to 011...1 does not cause an overflow in the n-bit adder, i.e., the carry flag would not be set in this case. Only the interpretation of the first bit as a sign bit produces the "wrap around" effect. – laune Jul 21 '15 at 13:54
  • @laune It is an overflow in the sense that the [overflow, or "V", flag](https://en.wikipedia.org/wiki/Overflow_flag) would be set as the result. – Sergey Kalinichenko Jul 21 '15 at 14:12
  • I presume that checking the overflow flag is how `Math.negateExact(int)` is intrinsified. – the8472 Jul 21 '15 at 16:33
  • @the8472 The exact answer to this depends on the hardware, but on most common hardware platforms in use today, the V flag would probably be the answer. – Sergey Kalinichenko Jul 21 '15 at 16:38