类型铸造差异

时间:2015-05-21 17:19:19

标签: c++ algorithm syntax

在以下代码中:

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;
}

我得到了

的输出
  

百万亿

这两条线有什么区别?为什么在第一种情况下不进行类型转换?

3 个答案:

答案 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 longlong long使用long long结果执行乘法,避免溢出。

相反,乘法运算符先于类型转换,然后表达式将被解释为:

(long long) (f * f)

具有两个int参数的乘法将执行int乘法,其给定f的值,先溢出然后然后被强制转换为{ {1}}。

要明确你的问题,

  

为什么在第一种情况下不会发生类型转换?

确实如此;但是发生得太晚了。