c ++比较函数结果

时间:2014-01-28 19:11:50

标签: c++ gcc g++

我有以下代码表现出一些非常奇怪的行为。有没有人知道为什么。

#include <iostream>

long global = 20001;

double foo() {return global / 1000.0;}

int main(int,char**) {
  if (foo() == foo()) {
    std::cout << "true\n";
  } else {
    std::cout << "false\n";
  }

  return 0;
}

这应该打印为true,因为函数每次返回相同的结果,而是打印false;

这是在Solaris 10上使用g ++构建的。 我不知道操作系统是否重要,但我没有机会在不同的操作系统上尝试它

2 个答案:

答案 0 :(得分:3)

操作系统可能并不重要,但编译器和 建筑做。在英特尔,通常的惯例是返回 浮点寄存器中的浮点值,具有 64位精度(而不是双精度的53)。并且 当然,编译器直接将算术运算到那里 注册,所以你最终返回64位的值 精度。

当然,当编译器生成调用函数的代码时, 它不能将值保留在寄存器中,因为函数可能会 使用该注册。所以它将它溢出到记忆中。作为双倍 56位。 ==运算符将此56位值进行比较 首先用第二个64位值调用,然后找到 他们不平等。

我可能会补充一点,如果编译器内联函数,问题可能就会消失。

根据标准,所有这些都是完全合法的。

答案 1 :(得分:1)

双打不能一直评估到完全相同的值(基本上是舍入错误)的问题。

如果要更改函数以返回整数,则可能会出现预期的行为。

与此问题非常相似: Deals with comparing floats

试试这个:

#include <iostream>
#include <limits>

long   global = 20001;
double epsilon = std::numeric_limits::epsilon<double>();

double foo() {return global / 1000.0;}

int main(int,char**) {
  if (foo() - foo() > epsilon) {
    std::cout << "true\n";
  } else {
    std::cout << "false\n";
  }

  return 0;
}