Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting result of multiplication two positive integers to long is negative value

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.

like image 573
Roman Nazarevych Avatar asked Oct 12 '12 15:10

Roman Nazarevych


2 Answers

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 ints, 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.

like image 65
Stephen C Avatar answered Oct 29 '22 15:10

Stephen C


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.

like image 22
SLaks Avatar answered Oct 29 '22 16:10

SLaks