【发布时间】:2020-09-22 05:05:09
【问题描述】:
#include <cstdio>
int main(void)
{
int val = 500;
printf("%d\n", (int)((long double)val / 500));
printf("%d\n", (int)((long double)500 / 500));
}
显然它应该输出1 1。但是如果你用-Ofast编译,就会输出0 1,为什么?
如果你把500改成其他值(比如400),用-Ofast编译,还是会输出1 1。
带有-Ofast的编译器资源管理器:https://gcc.godbolt.org/z/YkX7fB
似乎这条线导致了问题。
【问题讨论】:
-
将
val更改为小于 500 会得到 0。但我不确定您是否假设(int)(500./500)显然是 1。 -
在第一个中,也许是快速优化导致编译器生成乘以
0.001999999999而不是除法的代码。在第二个中,它可能根本不会在运行时计算。 -
@cigien 这不是重点。关键是
printf语句应该输出相同的值,因为它们本质上是(int)(500./500)。 -
不必必须输出相同的值。第二个允许编译器生成
puts("1"); -
只是一个猜测,但我认为启用
-ffast-math的编译器可以将/500计算为*(1.0/500)。如果这个值被四舍五入,那么乘以(long double)500可能会略低于1,并且转换为int总是会截断,最终会产生0。
标签: c++ c compilation g++ compiler-optimization