什么是float和double比较的最有效方法?

125 浏览
0 Comments

什么是float和double比较的最有效方法?

比较两个 doublefloat 值的最有效方法是什么?

简单地比较是不正确的:

bool CompareDoubles1 (double A, double B)
{
   return A == B;
}

但像这样:

bool CompareDoubles2 (double A, double B) 
{
   diff = A - B;
   return (diff < EPSILON) && (-diff < EPSILON);
}

似乎浪费资源。

有人知道更聪明的浮点数比较器吗?

admin 更改状态以发布 2023年5月22日
0
0 Comments

将数值与 epsilon 值比较是大多数人所做的(即使在游戏编程中也是如此)。

不过,您应该稍微修改一下您的实现:

bool AreSame(double a, double b)
{
    return fabs(a - b) < EPSILON;
}


编辑:Christer 在 最近的一篇博客文章中添加了一堆关于这个主题的精彩信息。尽情享受。

0
0 Comments

使用其他建议时一定要非常小心,一切都取决于上下文。

我花了很长时间追踪一个系统中的bug,该系统假定如果|a-b|,则a==b。其根本问题是:

  1. 算法中的隐含假设:"如果a==bb==c,则a==c"。

  2. 对于以英寸和mil(.001英寸)作为度量单位的线条使用相同的epsilon。这意味着a==b1000a!=1000b。(这就是为什么AlmostEqual2sComplement要求epsilon或max ULPS的原因)

  3. 将角的余弦和线的长度使用相同的epsilon进行比较!

  4. 使用这样的比较函数对集合中的项目进行排序。(在这种情况下,为双精度型使用内置的C++运算符==可以产生正确的结果。)

就像我说过的,一切都取决于上下文和期望的ab的大小。

顺便说一句,std::numeric_limits::epsilon()是“机器epsilon”。它是双精度值能够表示的下一个值与1.0的差值。我想它可以用于比较函数,但前提是期望值小于1。(这是针对@cdv的答案的回应...)

此外,如果基本上在doubles中进行int算术运算(在某些情况下我们使用doubles来表示int值),则算术运算将是正确的。例如,4.0/2.0将与1.0+1.0相同。只要不做会导致小数(4.0/3.0)或超出int大小的事情,这也是可以的。

0