我實現了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的其他實現是否只是不知道這個問題,或者如果我在我的原始實現中犯了一個錯誤?
謝謝,太棒了。這解決了問題!由於如果符號aInt和bInt相等,intDiff不會產生下溢。 –