类型铸造差异

Type casting differnce

本文关键字:类型      更新时间:2023-10-16

在以下代码中:

#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;
}
我得到了 的输出

276447232

但是如果我写

long long i=max((long long)1000000,(long long)f*f);
我得到了 的输出

100000000000000

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

这一行表示:"取这两个int值的最大值,后者将溢出。然后将结果转换为long long"。在第一种情况下调用long long强制转换时,已经太晚了。有符号整数溢出是未定义的行为。

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

如果在这一行展开宏:

long long i=(long long)max(1000000,f*f);

:

long long i=(long long)(1000000>f*f?1000000:f*f)

括号中的项是数据类型int,因此f*f被计算为整数并溢出到值<1000000。

由于c++运算符优先级规则,

(long long)f*f

在乘法之前进行类型转换。也就是说,该表达式与

相同。
((long long) f) * f

因为乘法的一个参数是long long,另一个参数(即裸f)也隐式地提升为long long,并且long long乘法使用long long结果执行,避免了溢出。

如果在类型转换之前使用乘法运算符,则表达式将被解释为:

(long long) (f * f)

有两个int参数的乘法将执行int乘法,给定f的值,首先溢出,然后类型转换为long long

为了明确你的问题,

为什么第一种情况下不进行类型转换?

它;但为时已晚。