什么是最有效的浮动和双重比较方式? [英] What is the most effective way for float and double comparison?
问题描述
比较两个 double
或两个 float
值的最有效方法是什么?
$ p
$ Compare $(double A,double B)
{
return A == B;
$ / code>
但是像这样:
bool CompareDoubles2(double A,double B)
{
diff = A - B;
return(diff< EPSILON)&& (-diff< EPSILON);
好像浪费了处理。
有谁知道一个更聪明的浮点比较器?
使用任何其他建议时要非常小心。这一切都取决于上下文。
如果 a == b
,我花了很长时间来追踪系统中的错误$ C> | AB |<小量。潜在的问题是:
-
算法中的隐含推定如果
a == b
和
b == c
然后a == c
。 使用相同的epsilon以英寸为单位,以mils(0.001英寸)为单位。那是a == b
但是1000a!= 1000b
。 (这就是为什么AlmostEqual2sComplement要求epsilon或max ULPS)。
对于角度的余弦和线的长度,使用相同的epsilon!
使用这种比较函数对集合中的项进行排序。 (在这种情况下,使用内置的C ++运算符==为双打产生了正确的结果。)
像我说的:都取决于上下文和预期的大小
a
和b
。
BTW,std :: numeric_limits< double> :: epsilon()
是机器epsilon。这是1.0和下一个值可以用double来表示的区别。我猜它可以在比较函数中使用,但只有当期望值小于1时(这是对@ cdv的答案的回应...)
另外,如果你在
doubles
中基本上有int
算术(在某些情况下我们使用double来保存int值)算术将是正确的。例如4.0 / 2.0将与1.0 + 1.0相同。这是只要你不做分数(4.0 / 3.0)的事情,或不超过一个int的大小。What would be the most efficient way to compare two
double
or twofloat
values?Simply doing this is not correct:
bool CompareDoubles1 (double A, double B) { return A == B; }
But something like:
bool CompareDoubles2 (double A, double B) { diff = A - B; return (diff < EPSILON) && (-diff < EPSILON); }
Seems to waste processing.
Does anyone know a smarter float comparer?
解决方案Be extremely careful using any of the other suggestions. It all depends on context.
I have spent a long time tracing a bugs in a system that presumed
a==b
if|a-b|<epsilon
. The underlying problems were:The implicit presumption in an algorithm that if
a==b
andb==c
thena==c
.Using the same epsilon for lines measured in inches and lines measured in mils (.001 inch). That is
a==b
but1000a!=1000b
. (This is why AlmostEqual2sComplement asks for the epsilon or max ULPS).The use of the same epsilon for both the cosine of angles and the length of lines!
Using such a compare function to sort items in a collection. (In this case using the builtin C++ operator == for doubles produced correct results.)
Like I said: it all depends on context and the expected size of
a
andb
.BTW,
std::numeric_limits<double>::epsilon()
is the "machine epsilon". It is the difference between 1.0 and the next value representable by a double. I guess that it could be used in the compare function but only if the expected values are less than 1. (This is in response to @cdv's answer...)Also, if you basically have
int
arithmetic indoubles
(here we use doubles to hold int values in certain cases) your arithmetic will be correct. For example 4.0/2.0 will be the same as 1.0+1.0. This is as long as you do not do things that result in fractions (4.0/3.0) or do not go outside of the size of an int.这篇关于什么是最有效的浮动和双重比较方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!