Overflowing Short in java
I have one question about the short
data type in Java. I know that the range for short is between -32768 to 32767.
So, if I tried to add two short values that exceed the range, the result ends up being the supposed total minus either the positive range or the negative range times 2, as the following:
short a = 30000;
a = (short) (a+a);
the result is -5536.
So the math is 32768 + 32768 = 65536, 6000 - 65536 = -5536.
I know what it does, but I don't know why it does it this way.
Can anybody explain the logic or why Java is doing it this way?
Solution 1:
What's happening is that your number is wrapping around. More specifically, you've got a number 30,000, which in binary is:
0111 0101 0011 0000
When you add it to itself, and carry the 1's, you get:
1110 1010 0110 0000
(Note: it's very easy to multiply a number by 2 in binary -- just shift all the bits one to the left.)
A short is a signed number using two's complement, meaning that that leftmost 1 is really a minus sign; that number represents -5536.
If you multiplied that number by 2 again, you'd need more than 2 bytes to represent it. Since you don't have more than 2 bytes in a short
, the extra bits would just get dropped when the int
result of the expression is narrowed to a short
. Do that enough, and you'll have a 0 as the leftmost digit; the number is positive again. And then eventually you'll have a 1 again as the leftmost; the number is negative again. Eventually you'll have shifted all 0s into the number; multiplying any integer by 2 enough times will always result in 0 (specifically, if it's an N-bit number, multiplying it by 2 N times will always result in 0).
If you weren't narrowing to a short
, you'd still eventually run out of digits in the int
(when you need 33 or more bits) -- this would result in the extra digits being dropped, which is integer overflow. The same thing would happen if either argument were a long
, though it would take 65+ bits.
Solution 2:
First, your addition converts the shorts into int because the additive operator performs a binary numeric promotion on the operands.
The result is therefore int tmp = 60000;
That result is then converted back to a short via a narrowing primitive conversion:
A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits, where n is the number of bits used to represent type T.
In other words 60000 = 1110 1010 0110 0000b
but short is signed so the initial 1 is the sign and using 2 complement, you get the equivalent short value, which is -5536: 1110 1010 0110 0000
=> -0001 0101 1010 0000
(you negate all the bits, add one and put a minus sign)
Solution 3:
0111 0101 0011 0000
+ 0111 0101 0011 0000
______________________
1110 1010 0110 0000
Java's short
is encoded in two's complement. In two's complement the Most Significant Bit is considered as the sign bit, 0
is positive and 1
and negative.
1110 1010 0110 0000 = -5536 in two's complement
Solution 4:
It has to do with the binary representation of data. In most systems, something called 2's complement is used. Positive numbers behave normally, as long as they have a leading 0.
0010 = 2
To flip the sign, replace all 0's with 1's, and add 1:
-2 = 1110
So what happens if we take the biggest positive number, say, 01111 (in binary), and add 1? We get 10000, which is a negative number (Int.min_val, specifically). That's what happens when an integer overflows.
http://en.wikipedia.org/wiki/Two%27s_complement