/ fp的奇怪结果:快

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开关,但这会使我们的应用程序慢一点.

Den*_*ose 6

我对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标志.或者您可以将此例程移动到单独的文件并为该文件提供自定义标志.无论哪种方式,它可以防止你的整个程序只是为了保持一个例程快乐.

  • 是的,尝试`#pragma float_control(...)`for Visual Studio:http://msdn.microsoft.com/en-us/library/45ec64h6.aspx - 你可以禁用fp:fast只围绕有问题的函数. (2认同)