c ++如果双精度值的条件检查给出意外输出

c++ if condition check of double values gives unexpected output

#include <iostream>

using namespace std;

int
main ()
{
  double a = 0.01;
  double b = 45.01 - 45;
  double c = b;

  if (a == c)
    cout << "a is 0.01" << '\n';
  else
    cout << "a is not 0.01" << '\n';

  return 0;
}

运行 上面的代码给出了输出 "a is not 0.01" 而不是 "a is 0.01"。我不明白为什么 if 语句会弄乱 a 和 c 的双精度值?这里为什么 a 不等于 b 和 c?我应该怎么做才能获得 "a is 0.01" 的预期输出?

这是一道浮点运算题。

运行这个:

#include <iostream>

using namespace std;

int main () {
  double a = 0.01;
  double b = 45.01 - 45;
  double c = b;
  std::cout << a-c << std::endl;
  return 0;
}

将给出此输出:

1.98973e-015

这是因为浮点数在 C++ 中的表示方式。

您可以做的一件事是使用 round() 函数(c++11 或更高版本的编译器)或将结果转换为整数并进行少量修改来对结果进行舍入。

我更喜欢转换选项,因为在某些情况下,如果结果为负,则使用 round() 函数需要进行更多修改。

  double d = int( (a - c) * 100) / 100;
  std::cout << d << std::endl;

将给出以下输出:

  0

因此,这将起到作用:

#include <iostream>
using namespace std;

int main () {
  double a = 0.01;
  double b = 45.01 - 45;
  double c = b;

  double d = int( (a - c) * 100) / 100;

  if (!d) // equivalent to (d == 0)
    std::cout << "a is 0.01" << std::endl;
  else
    std::cout << "a is not 0.01" << std::endl;

  return 0;
}

您可以阅读以下内容以更好地理解问题 -

What Every Computer Scientist Should Know About Floating-Point Arithmetic

Comparing Floating Point Numbers, 2012 Edition

您也可以查看this question中的答案,我从中获得了推荐文章。

编辑: 正如 Artyer 所指出的,这是一种将值四舍五入的方法。 如果使用此方法,则需要替换 '100' int:

double d = int( (a - c) * 100) / 100;

10^x,其中 x 将是您想要的小数精度。