2012-09-14 25 views
1

我实现了Bruce Dawson建议的AlmostEqual2sComplement,但是用于比较double而不是float值。AlmostEqual2sComplement实现不处理简并案例

类似的实现可以在许多地方找到。

bool AlmostEqual2sComplement(double A, double B, int maxUlps= 10) 
{ 
    // 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; 

    long long aInt = *(long long*)&A; 
    // Make aInt lexicographically ordered as a twos-complement int 
    if (aInt < 0) 
     aInt = 0x8000000000000000 - aInt; 

    // Make bInt lexicographically ordered as a twos-complement int 
    long long bInt = *(long long*)&B; 
    if (bInt < 0) 
     bInt = 0x8000000000000000 - bInt; 

    long long intDiff = aInt - bInt; 
    if (intDiff < 0) 
     intDiff= intDiff*-1; 

    if (intDiff <= maxUlps) 
     return true; 
    return false; 
} 

不幸的是,当比较double值-1.0和4.0时,函数返回true。 这是因为在这种情况下,intDiff结果等于0x8000000000000000和 的0x8000000000000000绝对值再次0x8000000000000000

我目前的解决这个问题是不是采取intDiff的绝对值,而是改变intDiff的对比和maxUlps到:

if (intDiff <= maxUlps && -maxUlps <= intDiff) 
    return true; 

必须有更多的(也许不那么明显)的情况下intDiff结果0x8000000000000000

我想知道AlmostEqual2sComplement的其他实现是否只是不知道这个问题,或者如果我在我的原始实现中犯了一个错误?

回答