Last Updated: February 25, 2016
·
1.725K
· tttthomasssss

In Java, Integer.MIN_VALUE == -Integer.MIN_VALUE

Its quite obvious when you think about whats going on (Integer Overflow, see more below), yet its so easy to forget about it and one ends up looking for bugs where there are no bugs to be found!

Try the following code snipped and see for yourself.


// Ouch
int alpha = Integer.MIN_VALUE;
int beta = Integer.MAX_VALUE;

System.out.println("ALPHA: " + alpha);
System.out.println("BETA: " + beta);
System.out.println("-ALPHA: " + (-alpha));
System.out.println("-BETA: " + (-beta));
System.out.println("ALPHA == -ALPHA: " + (alpha == -alpha));
System.out.println("BETA == -BETA: " + (beta == -beta));

// Better
alpha = Integer.MIN_VALUE + 1;
beta = Integer.MAX_VALUE;

System.out.println("ALPHA: " + alpha);
System.out.println("BETA: " + beta);
System.out.println("-ALPHA: " + (-alpha));
System.out.println("-BETA: " + (-beta));
System.out.println("ALPHA == -ALPHA: " + (alpha == -alpha));
System.out.println("BETA == -BETA: " + (beta == -beta));

Now in most cases that might not actually matter because you're not going to flip the sign of variables containing Integer.MIN_VALUE, however, in these rare cases where you do, bear in mind that Integer.MIN_VALUE == -Integer.MIN_VALUE.

The reason for it, as already mentioned above, is Integer Overflow. Integer.MIN_VALUE = -2^31 and INTEGER.MAX_VALUE = 2^31 - 1. So when you do -Integer.MIN_VALUE, it would result in -(-2^31), so 2^31, which doesn't fit into a Java Integer (Hello, two's-complement representation)!

A more elaborate explanation can be found in the Java spec.

The important part saying the following:

"If an integer addition overflows, then the result is the low-order bits of the mathematical sum as represented in some sufficiently large two's-complement format. If overflow occurs, then the sign of the result is not the same as the sign of the mathematical sum of the two operand values."