4 回答
TA贡献1827条经验 获得超9个赞
使用任何其他建议时要格外小心。这一切都取决于背景。
我花了很长时间跟踪系统中的错误,假设a==b是|a-b|<epsilon。潜在的问题是:
算法中隐含的假设,if
a==b和b==cthena==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大小的事情。
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; }添加回答
举报
