在以下代码中:
cd /<whateverTheFolderStructure>/public/upload/user
ls -ah
我得到了
的输出276447232
但如果我写
#include<cstdio>
#define max(a,b) (a>b?a:b)
using namespace std;
int main()
{
int f=10000000;
long long i=(long long)max(1000000,f*f);
printf("%lld",i);
return 0;
}
我得到了
的输出百万亿
这两条线有什么区别?为什么在第一种情况下不进行类型转换?
答案 0 :(得分:6)
这一行说:“取这两个int
值的最大值,后者将溢出。然后取结果并将其转换为long long
”。在第一种情况下调用long long
强制转换时,为时已晚。 Signed integer overflow is undefined behavior
long long i=(long long)max(1000000,f*f)
这一行说:“取这两个long long
值中的最大值并将其返回”。 (long long)f*f
之所以有效,是因为由于优先级,它会在乘法之前将第一个f
转换为long long
。然后将第二个f
提升为long long
,以便进行乘法运算。
long long i=max((long long)1000000,(long long)f*f);
答案 1 :(得分:2)
如果您在此行中展开宏:
$3
你得到:
long long i=(long long)max(1000000,f*f);
括号中的术语是数据类型int,因此f * f被计算为整数并且溢出环绕到值&lt;百万。
答案 2 :(得分:0)
由于C++ operator precedence rules,
(long long)f*f
乘法前的类型转换。也就是说,该表达式与:
相同((long long) f) * f
因为乘法的一个参数是long long
,另一个参数(即裸f
)也被隐式提升为long long
,long long
使用long long
结果执行乘法,避免溢出。
相反,乘法运算符先于类型转换,然后表达式将被解释为:
(long long) (f * f)
具有两个int
参数的乘法将执行int
乘法,其给定f
的值,先溢出然后然后被强制转换为{ {1}}。
要明确你的问题,
为什么在第一种情况下不会发生类型转换?
确实如此;但是发生得太晚了。