Reputation: 113
The following piece of code gives the correct result for the multiplication
int var0 = 245895;
int var1 = 478565
long long val = 0;
val = (long long) var0 * var1;
but this piece gives the incorrect result:
int var0 = 245895;
int var1 = 478565
long long val = 0;
val = (long long) (var0 * var1);
Could anybody help me with why?
Upvotes: 8
Views: 4915
Reputation: 56479
(long long) var0 * var1
~~~~~~~~~~~~~~~~
1
~~~~~~~~~~~~~~~~~~~~~~~
2
In the above code, first var0
casts to long long
, after that, the result of multiplication will be calculated as long long
with no overflow. In fact compiler promotes the type of var1
from int
to long long
implicitly.
(long long) (var0 * var1)
~~~~~~~~~~~~~
1
~~~~~~~~~~~~~~~~~~~~~~~~~
2
In the second code, first multiplication occurs and the result doesn't fit in a long
type, so the cast after that doesn’t help anymore. It casts the number that is overflow-ed before.
Therefore, the first one is better than second one to avoid overflows.
Upvotes: 17
Reputation: 4925
It's all a matter of how the mid calculation result is stored:
val = (long long) (var0 * var1);
is interpreted as:
int midResult = (int)var0 * (int)var1;
val = (long long)midResult;
While, val = (long long) var0 * var1
is interpreted as:
long long midResult = (long long) var0 * (long long)var1;
Upvotes: 3
Reputation: 16041
In the first, you are casting var0
to long long
then multiply it with var1
, in the second you multiply the two variables, then cast the result to long long
. The latter is more prone to integer overflow, because of the smaller bit count.
And regarding precendence: multiplication has the precedence of 3, while parentheses have the precedence of 1 - the highest possible. For the complete list of operator precedence, please take a look here.
Upvotes: 0