以下代码为乘法提供了正确的结果
int var0 = 245895;
int var1 = 478565
long long val = 0;
val = (long long) var0 * var1;
但这件作品的结果不正确:
int var0 = 245895;
int var1 = 478565
long long val = 0;
val = (long long) (var0 * var1);
有人可以帮我解释原因吗?
答案 0 :(得分:7)
(long long) var0 * var1
~~~~~~~~~~~~~~~~
1
~~~~~~~~~~~~~~~~~~~~~~~
2
在上面的代码中,首先var0
转换为long long
,之后,乘法结果将计算为long long
且没有溢出。实际上,编译器会隐式地将var1
的类型从long
提升为long long
。
(long long) (var0 * var1)
~~~~~~~~~~~~~
1
~~~~~~~~~~~~~~~~~~~~~~~~~
2
在第二个代码中,首先进行乘法,结果不适合long
类型,因此之后的强制转换不再有用。它会抛出之前溢出的数字。
因此,第一个比第二个好,以避免溢出。
答案 1 :(得分:1)
所有关于如何存储中间计算结果的问题:
val = (long long) (var0 * var1);
被解释为:
int midResult = (int)var0 * (int)var1;
val = (long long)midResult;
虽然val = (long long) var0 * var1
被解释为:
long long midResult = (long long) var0 * (long long)var1;
答案 2 :(得分:0)
首先,您将var0
转换为long long
,然后将其与var1
相乘,在第二个中将两个变量相乘,然后将结果转换为long long
。由于位数较小,后者更容易出现整数溢出。
关于优先权:乘法的优先级为 3 ,而括号的优先级为 1 - 最高的。有关运算符优先级的完整列表,请查看here。