mar*_*nus 4 c++ floating-accuracy compiler-optimization visual-studio-2008
我们有一些看起来像这样的代码:
inline int calc_something(double x) {
if (x > 0.0) {
// do something
return 1;
} else {
// do something else
return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,当使用标志时/fp:fast,我们得到了calc_something(0)==1明显错误的代码路径.这只发生在我们在代码中的多个点使用不同参数的方法时,所以我认为编译器(Microsoft Visual Studio 2008,SP1)中存在一些可疑的优化.
此外,当我们将接口更改为时,上述问题也消失了
inline int calc_something(const double& x) {
Run Code Online (Sandbox Code Playgroud)
但我不知道为什么这会解决这个奇怪的行为.任何人都可以解释这种行为吗?如果我无法理解发生了什么,我们将不得不删除/fp:fast开关,但这会使我们的应用程序慢一点.
我对FPU的熟悉程度不够高,但我的猜测是编译器会让它认为应该等于的现有值等于x该比较.也许你y = x + 20.; y = y - 20; y已经在FP堆栈上,所以而不是加载x编译器只是比较y.但是由于四舍五入的错误,y它不0.0应该像它应该的那样,并且你会看到奇怪的结果.
为了更好的解释:为什么cos(x)!= cos(y)即使x == y?来自C++ FAQ lite.这是我想要解决的问题的一部分,我只是记不清楚到目前为止我在哪里阅读它.
更改为const引用会修复此问题,因为编译器担心别名.它强制加载,x因为它不能假设它的值在创建后的某个时刻没有改变y,并且因为x实际上正好0.0[在我熟悉的每个浮点格式中都可以表示]舍入错误消失了.
我很确定MS提供了一个pragma,它允许你在每个函数的基础上设置FP标志.或者您可以将此例程移动到单独的文件并为该文件提供自定义标志.无论哪种方式,它可以防止你的整个程序只是为了保持一个例程快乐.
| 归档时间: |
|
| 查看次数: |
958 次 |
| 最近记录: |