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; }添加回答
舉報
