I have code like this :
int a = 629339;
int b = 4096;
long res = a*b;
The result is -1717194752
but if I add one manual cast to long long res = ((long)a)*b;
or long res = (long) a*b;
the result is correct 2577772544
Who can explain how does it works.
You have to break the assignment statement into its parts to understand what is doing on:
long res = a*b;
Step 1 is to get the values of a
and b
.
Step 2 is to evaluate a * b
. Since a
and b
are both int
s, this is an int
multiplication. So we multiply 629339
by 629339
which would be 2577772544
.
Unfortunately, 2577772544
is larger than the largest possible Java int
value ... so the multiplication operation silently overflows ... and we get -1717194752
instead.
Step 3 we assign the value of the RHS to the LHS. Since the RHS is int
and the LHS is float
, the JLS says we perform a primitive widening conversion ... which simply turns -1717194752
into a long
with the same value. The widened value is then assigned to res
.
To get the answer that you are expecting, we have to force multiplication to be performed using long
arithmetic. For example:
long res = ((long) a) * b;
In this case, we have a multiplication of a long
by an int
, and this is handled by widening the int
to a long
and performing a long
multiply. This no longer overflows (because 2577772544
is well below the largest long
value), so when we finally assign the value to res
, it is the number that you were expecting.
a*b
is an integer, not a long.
Because it's only an integer, it has already wrapped around the 32-bit limit.
Casting this integer back to long will not magically recover that data.
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