什么是float和double比较的最有效方法?
什么是float和double比较的最有效方法?
比较两个 double
或 float
值的最有效方法是什么?
简单地比较是不正确的:
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日
将数值与 epsilon 值比较是大多数人所做的(即使在游戏编程中也是如此)。
不过,您应该稍微修改一下您的实现:
bool AreSame(double a, double b) { return fabs(a - b) < EPSILON; }
编辑:Christer 在 最近的一篇博客文章中添加了一堆关于这个主题的精彩信息。尽情享受。
使用其他建议时一定要非常小心,一切都取决于上下文。
我花了很长时间追踪一个系统中的bug,该系统假定如果|a-b|
a==b
。其根本问题是:
-
算法中的隐含假设:"如果
a==b
和b==c
,则a==c
"。 -
对于以英寸和mil(.001英寸)作为度量单位的线条使用相同的epsilon。这意味着
a==b
但1000a!=1000b
。(这就是为什么AlmostEqual2sComplement
要求epsilon或max ULPS的原因) -
将角的余弦和线的长度使用相同的epsilon进行比较!
-
使用这样的比较函数对集合中的项目进行排序。(在这种情况下,为双精度型使用内置的C++运算符
==
可以产生正确的结果。)
就像我说过的,一切都取决于上下文和期望的a
和b
的大小。
顺便说一句,std::numeric_limits
是“机器epsilon”。它是双精度值能够表示的下一个值与1.0
的差值。我想它可以用于比较函数,但前提是期望值小于1。(这是针对@cdv的答案的回应...)
此外,如果基本上在doubles
中进行int
算术运算(在某些情况下我们使用doubles来表示int值),则算术运算将是正确的。例如,4.0/2.0
将与1.0+1.0
相同。只要不做会导致小数(4.0/3.0
)或超出int大小的事情,这也是可以的。