Quinma
Quinma

Reputation: 1476

Java Integer.MIN_VALUE's negative then compare yields two negatives

I have a test tomorrow and I can't understand my books explanation, I appreciate the help:

public class TestClass{
      public static void main(String[] args) throws Exception{
            int a = Integer.MIN_VALUE;
            int b = -a;
            System.out.println( a+ "   "+b);
      }
}

Output: -2147483648 -2147483648

Why does this print 2 negative numbers of the same magnitude and not a positive and negative?

Upvotes: 23

Views: 26239

Answers (5)

Java ints are stored in a 32-bit two's compliment form. Similar results applies for all two's compliment representations. The anomalous behavior is due to the extra negative integer which is an artifat of two's compliment.

-2147483748 has a leadbitwise representation of

10000000 00000000 00000000 00000000

and the negative of a number is achieved by flipping all the bits and adding one to it. The largest positive int will have a bitwise representation of

01111111 11111111 11111111 11111111

which is 2147483647. We then add one more, so bitwise, we have

10000000 00000000 00000000 00000000 == -2147483648

This extra integer is an artifact of the two's compliment representation and operations with this number can have undesirable consequences. -2147483748 is indeed unique among the ints!

Upvotes: 0

Mad Physicist
Mad Physicist

Reputation: 114558

A fixed number of binary bits can encode an even number of things. That means that you can't have a sequence that's exactly centered on zero, since that would require an is number of things to be symmetrical. The closest thing you can get to having zero in the middle of the sentence is to split it as either negative and non-negative, or positive and non-positive. Normal twos complement encoding does the former. So 32 bits span the range from -2^31 to 2^31-1. Zero is in the non-negative half of the sequence, and you have one negative number that can not be properly negated.

Upvotes: 0

user2332921
user2332921

Reputation: 369

To show this even more clearly:

Integer.MIN_VALUE is -2^31 = -2147483648
Integer.MAX_VALUE is 2^31-1 = 2147483647 
/*notice this is 1 less than the negative value above*/

Integer.MAX_VALUE can not take 2147483648. This is too large number for Integer by exactly 1. This causes the number to go back on the scale from max value back to starting poing which is the min value.

Upvotes: 3

assylias
assylias

Reputation: 328913

Because of silent integer overflow: Integer.MIN_VALUE is -2^31 and Integer.MAX_VALUE is 2^31-1, so -Integer.MIN_VALUE is 2^31, which is Integer.MAX_VALUE + 1, which by definition is too large for an integer. So it overflows and becomes Integer.MIN_VALUE...

You can also check that:

System.out.println(Integer.MAX_VALUE + 1);

prints the same thing.

More technically, the result is defined by the Java Language Specification #15.18.2:

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.

Upvotes: 42

João Mendes
João Mendes

Reputation: 1435

Basically, because Integer.MAX_VALUE is actually only 2147483647, so -Integer.MIN_VALUE, which would be +2147483648, actually overflows the capacity of the internal binary representation of integers. Thus, the result "loops around" back to Integer.MIN_VALUE, or -2147483648.

If you did long b = -((long)a); instead, you would get the expected result.

Upvotes: 5

Related Questions