将双精度与双精度文本进行比较

Comparing doubles to double literals?

本文关键字:双精度 比较 文本      更新时间:2023-10-16

可能的重复项:
我应该如何进行浮点比较?

不建议在C++中比较双精度和双精度文字的相等性,因为我想它是编译器依赖的?

更准确地说,比较硬编码的双精度(源代码中的文字)和应该计算的双精度是不行的,因为计算结果的最后一个数字可能因编译器而异。这不是标准化的吗?

我听说高德纳的TeXbook中提到了这一点,对吗?

如果这一切都是真的,解决方案是什么?

你有点误解了这个建议。关键是浮点计算并不精确。发生舍入误差,精度逐渐丢失。拿一些简单的事情来说1.0/10.0.结果应该是 0.1 ,但事实并非如此,因为0.1不能以浮点格式精确表示。所以实际结果会略有不同。无数其他操作也是如此,因此这一点与常量双精度无关。这与不期望结果准确有关。如果你执行一些计算,结果应该是1.0,那么你不应该测试它是否相等1.0,因为舍入误差可能意味着它实际上是0.9999999997出来的。

所以通常的解决方案是 测试结果是否足够接近1.0 .如果它很接近,那么我们假设"它足够好",并表现得好像结果是 1.0。

底线是,浮点值很少使用严格相等。相反,您应该测试两个值之间的差异是否小于某个小值(通常称为 epsilon

您正在谈论的问题是由于舍入错误造成的,并且每个浮点数都会发生。您可以做的是定义一个 epsilon 并查看两个浮点数之间的差异是否小于此值。例如:

double A = somethingA();
double B = somethingB();
double epsilon = 0.00001;
if (abs(A - B) < epsilon)
  doublesAreEqual();

[编辑] 另请参阅此问题:浮点数和双重比较的最有效方法是什么?

关键问题是浮点运算的工作原理 - 它包括四舍五入,这可能导致比较错误的相等性。这适用于所有浮点数,无论变量是否声明为const

如果您进行浮点计算并且需要与某些固定值进行比较,则使用 epsilon 值来考虑精度误差总是更安全的。

例:

double calcSomeStuf();
if ( calcSomeStuf() == 0.1 ) { ...}

是个坏主意

然而:

const double epsilon = 0.005
double calcSomeStuf();
if ( abs(calcSomeStuf() - 0.1) < epsilon ) { ...}

要安全得多(特别是考虑到 0.1 不能完全表示为双精度的事实)

这是必要的,因为当累积浮点运算时会发生舍入误差,并且由于浮点的性质,并非所有数字都可以精确表示