浮动和双重比较最有效的方法是什么?比较两个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);}似乎浪费处理。有谁知道更聪明的浮动比较器?
4 回答
素胚勾勒不出你
TA贡献1827条经验 获得超9个赞
使用任何其他建议时要格外小心。这一切都取决于背景。
我花了很长时间跟踪系统中的错误,假设a==b
是|a-b|<epsilon
。潜在的问题是:
算法中隐含的假设,if
a==b
和b==c
thena==c
。使用相同的epsilon测量以英寸为单位的线和以mils(.001英寸)测量的线。那是
a==b
但是1000a!=1000b
。(这就是AlmostEqual2sComplement要求epsilon或max ULPS的原因)。对于角度的余弦和线的长度,使用相同的epsilon!
使用这样的比较函数对集合中的项目进行排序。(在这种情况下,使用内置C ++运算符== for double产生了正确的结果。)
就像我说:这一切都取决于背景和预期的大小a
和b
。
BTW,std::numeric_limits<double>::epsilon()
是“机器epsilon”。它是1.0和下一个值之间的差值,可用双精度表示。我猜它可以在比较函数中使用,但只有在预期值小于1时才会使用。(这是对@ cdv答案的回应......)
另外,如果你基本上有int
算术doubles
(这里我们使用双精度来保存某些情况下的int值)你的算术是正确的。例如,4.0 / 2.0将与1.0 + 1.0相同。只要您不执行导致分数(4.0 / 3.0)或不超出int大小的事情。
哔哔one
TA贡献1854条经验 获得超8个赞
有关更深入的方法,请参阅比较浮点数。以下是该链接的代码段:
// Usable AlmostEqual function bool AlmostEqual2sComplement(float A, float B, int maxUlps) { // Make sure maxUlps is non-negative and small enough that the // default NAN won't compare as equal to anything. assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024); int aInt = *(int*)&A; // Make aInt lexicographically ordered as a twos-complement int if (aInt < 0) aInt = 0x80000000 - aInt; // Make bInt lexicographically ordered as a twos-complement int int bInt = *(int*)&B; if (bInt < 0) bInt = 0x80000000 - bInt; int intDiff = abs(aInt - bInt); if (intDiff <= maxUlps) return true; return false; }
添加回答
举报
0/150
提交
取消