簡體   English   中英

使用std :: max比較兩個雙打是否安全?

[英]Is using std::max for comparing two doubles safe?

我知道要比較兩個雙打,我們必須做這樣的事情

bool AreSame(double a, double b)
{
    return fabs(a - b) < EPSILON;
}

但是我不知道std :: max是否以相同的方式比較兩個雙精度值,或者是否以相同的方式安全比較? 如果我調用std::max(0.1,0.11)那將是答案。 我得到了正確的結果,但是仍然不確定! Morover我昨晚在codeforces上使用了它,並接受了我的解決方案!

我為什么擔心? 我檢查了http://www.cplusplus.com/是否已寫成max的行為與以下代碼相同

template <class T> const T& max (const T& a, const T& b) {
  return (a<b)?b:a;     // or: return comp(a,b)?b:a; for version (2)
}

頁面鏈接

(相對差為10 ^ -6)

std::max不關心相等性,它只關心兩個數字不相等時的情況。 另外,ε問題與尋找近似相等的數字有關,其差是由浮點誤差引起的。 浮點錯誤應導致std::max選擇另一個作為std::max因為std::max無法知道哪種epsilon是合適的。

請記住,您的系統可能希望AreSame(0.1000001, 0.1) == truestd::max(0.1000001, 0.1)應該返回0.1000001 ,以防萬一。

(正如您剛剛修改的問題一樣)max應該做一個簡單的“ <”,例如

(a < b) ? b : a

這應該是“安全的”,因為您可以在兩個雙打/浮點數之間進行比較。 但是,雙精度數/浮點數實際上只是值的近似值,它們可能是也可能不是確切值。 您可以在以10為基數的值中看到一個類似1/3 = .3333的值...寫入的十進制值永遠不可能是精確的1/3,因為它是一個無限重復的值。 為了使處理器能夠使用離散值,必須使用有限數量的位,因此將發生舍入。 這使“等於”的概念有些混亂,您實際上是在說兩個值近似相等,在給定一定的公差(ε)的情況下足夠接近。 您可以認為>和<也受此近似過程的變化影響。 但是,通常人們願意接受具有<或>關系的兩個值的“更廣泛”的想法。

實際上這可能是一個非常復雜的問題。 這在很大程度上取決於您的工作以及您的應用程序對這些數值近似問題的容忍程度。 我知道一種情況的AI算法使用FPU的指令使用MMX / SSE / AVX ...類型的指令(PC的FPU通常在80位內部計算然后圓形,而AVX指令使用64位受變化的干至船尾 )。 在許多迭代過程中,基於舍入的差異導致采用不同的路徑導致不同的結果。 這很大程度上與這些類型的比較有關。 您不能說這種方法(取決於FPU行為)是不正確的,只是不能容忍對“較低分辨率” FP計算的更改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM