Reputation: 1476
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
Reputation: 2613
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
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
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
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
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