我在Coursera上做MOOC,这段代码不起作用:
unsigned int W, H, D;
uint64_t total_weight = 0;
for (unsigned int i = 0; i < N; ++i) {
cin >> W >> H >> D;
total_weight += static_cast<uint64_t>(W * H * D);
}
total_weight *= R;
cout << total_weight;
然而,这个确实:
unsigned int W, H, D;
uint64_t total_weight = 0;
for (unsigned int i = 0; i < N; ++i) {
cin >> W >> H >> D;
total_weight += static_cast<uint64_t>(W) * H * D;
}
total_weight *= R;
cout << total_weight;
正如您所看到的,差异在于这一行:
total_weight += static_cast<uint64_t>(W) * H * D;
该演员如何与
不同total_weight += static_cast<uint64_t>(W * H * D);
答案 0 :(得分:3)
total_weight += static_cast<uint64_t>(W * H * D);
此处W * H * D
计算为unsigned int
s的乘法,然后转换为uint64_t
,这样可以在计算W * H * D
时避免潜在的溢出。
total_weight += static_cast<uint64_t>(W) * H * D;
此处static_cast<uint64_t>(W) * H * D
计算为uint64_t
的乘法,W
投放到uint64_t
和H
,D
提升为{ {1}}也是。因此,在这种情况下,乘法过程中出现溢出的可能性较小。
相关转换规则描述如下:
8表达式[expr]
11许多期望算术或算术操作数的二元运算符 枚举类型导致转换并产生类似的结果类型 办法。目的是产生一种普通类型,它也是一种类型 结果。这种模式称为通常的算术转换, 其定义如下:
...
11.5.2否则,如果两个操作数都有有符号整数类型或两者都有无符号整数类型,则操作数类型为较小的操作数 整数转换等级应转换为操作数的类型 排名更高。
和
7.15整数转换排名[conv.rank]
1每个整数类型都有一个定义为的整数转换等级 如下:
...
1.3 long long int的等级应大于long int的等级,该等级应大于int的等级,其应为 大于短int的等级,大于等于 签名字符的排名。
1.4任何无符号整数类型的等级应等于相应有符号整数类型的等级。