我已经经历了不同的线程来比较较小或较大的浮点值,而不等于比较,但不清楚我们是否需要epsilon值逻辑来比较较小或较大的浮点值?
e。g→
float a, b;
if (a < b) // is this correct way to compare two float value or we need epsilon value for lesser comparator
{
}
if (a > b) // is this correct way to compare two float value for greater comparator
{
}
我知道为了比较浮点数的相等性,我们需要一个值
bool AreSame(double a, double b)
{
return fabs(a - b) < EPSILON;
}
这实际上取决于当两个值足够接近而被视为相等时应该发生什么,即fabs(a - b) < EPSILON
。在某些用例中(例如计算统计数据),两个相近值之间的比较是否相等并不十分重要。
如果重要,您应该首先确定值的不确定度。这实际上取决于用例(输入值来自何处以及如何处理它们),然后两个差异小于该不确定性的值应该被认为是相等的。等式不再是一个真正的数学等价关系:你可以很容易地想象如何在两个真正不同的值之间建立一个接近值的链。在数学单词中,关系不是传递的(或者几乎传递的是当前语言单词)。
我很抱歉,但是一旦你必须处理近似,就不可能有任何精确和一致的方法:你必须考虑现实世界的用例来确定你应该如何处理近似。
在处理浮点数时,不可避免地会遇到精度错误。
为了缓解这种情况,在检查两个浮点是否相等时,我们经常检查它们的是否相差
然而,对于lesser和greater,没有办法完全确定哪个float更大。最好的方法(可能符合您的意图)是首先使用areSame
函数检查两个浮点数是否相同。如果是,返回false(因为a = b
意味着a < b
和a > b
都是false)。
否则,返回a < b
或a > b
的值。
答案取决于应用程序。
如果你确定a和b有足够的不同,数字错误不会颠倒顺序,则a <B已经足够好了。>
但是如果a和b非常接近,你可能需要
不用说,EPSILON的选择应该非常小心(这通常是相当困难的)。
这最终取决于您的应用程序,但我认为通常不会。
问题,非常简化,是如果你计算:(1/3) * 3
并得到答案0.999999
,那么你想比较等于1
。这就是为什么我们使用epsilon值来进行相等的比较(epsilon应该根据应用和期望的精度来选择)。
另一方面,如果你想对浮点数列表进行排序,那么默认情况下0.999999
值将在1
之前排序。但话说回来,什么才是正确的行为呢?如果它们都被排序为1
,那么哪一个实际上先排序是随机的(取决于列表的初始顺序和您使用的排序算法)。
浮点数的问题不在于它们是"随机的";而且不可能预测它们的确切值。问题是,以10为基数的分数不能清晰地转换为以2为基数的分数,而且一个系统中的非重复小数可以在另一个系统中转换为重复小数——当截断到有限数量的小数时,这会导致舍入误差。我们使用epsilon值进行相等比较,以处理由于来回转换而产生的舍入错误。
但是请注意,==
,<
和<=
对于整数的良好关系并不总是完全转换为浮点数,因为涉及到的epsilons。例子:
- a = x
- b = a + epsilon/2
- c = b + epsilon/2
- d = c + epsilon/2
Now:a == b
,b == c
,c == d
, BUTa != d
,a < d
。事实上,你可以继续保持num(n) == num(n+1)
的序列,同时得到a
和序列中最后一个数字之间的任意大的差值。
正如其他人所说,在处理浮点数时总是存在精度错误。
因此,即使比较小于/大于,也应该有一个epsilon值。
我们知道,为了使a
小于b
,首先,a
必须不同于b
。检查这是一个简单的NOT等号,用的是。然后,一旦您已经知道a != b
,操作符<
就足够了。