Consider this snippet from the Java language specification.
class Test {
public static void main(String[] args) {
int i = 1000000;
System.out.println(i * i);
long l = i;
System.out.println(l * l);
}
}
The output is
-727379968
1000000000000
Why is the result -727379968
for (i*i)
? Ideally it should be 1000000000000.
I know the range of Integer is from –2147483648 to 2147483647. so obviously 1000000000000 is not in the given range.
Why does the result become -727379968
?
The pseudocode to check against overflow for positive numbers follows: if (a > max_int64 / b) then "overflow" else "ok". To handle zeroes and negative numbers you should add more checks. To calculate carry we can use approach to split number into two 32-digits and multiply them as we do this on the paper.
Suppose we want to find the result after multiplying two numbers A and B. We have to check whether the multiplied value will exceed the 64-bit integer or not. If we multiply 100, and 200, it will not exceed, if we multiply 10000000000 and -10000000000, it will overflow.
So overflow can be detected by checking Most Significant Bit(MSB) of two operands and answer.
Lets look at the binary:
1000000 is 1111 0100 0010 0100 0000
.
1000000000000 is 1110 1000 1101 0100 1010 0101 0001 0000 0000 0000
However, the first two sections of 4 bits won't fit in an int
(since int
is 32-bits wide in Java,) and so they are dropped, leaving only 1101 0100 1010 0101 0001 0000 0000 0000
, which is -727379968
.
In other words, the result overflows for int
, and you get what's left.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With