2012-11-28 98 views
0

我想比較兩個包含雙精度的元組儘可能高效。如何有效比較包含雙等號的std :: tuple

由於浮點精度使用預定義的運算符==(...)無法完成此操作,所以最好的方法是什麼?我是否真的需要遍歷所有元組元素,還是有一些我可以使用的模板魔法,這可能允許編譯器調用一些SIMD優化?

+1

儘可能高效涉及某種形式運算符==。您似乎有其他要求(「由於浮點精度」),但不知何故相信您的唯一要求是效率。 –

+0

你應該試着正確地解決這個問題,因爲這對於雙打來說不是一件容易的事情,並且在你對它進行分析並試圖使它更有效率的情況下(如果可能的話) – PlasmaHH

+0

效率只是一個問題。另一個是數據集正在從一個文件中讀取,這就是爲什麼operator ==()幾乎不存在問題。 –

回答

6

這是一個誤解,即爲平等而比較浮點值會受到影響。在任何不可怕的實現中,當且僅當比較的值相等時,比較等式的浮點值才返回true。

任何實際的錯誤都出現在您的計算中。這些錯誤必須加以控制和表徵。如果沒有對錯誤的描述,就不可能提出任何適合您的目的的操作的建議。

如果您的值的計算不精確,以便它們可能包含一些錯誤,並且您希望接受爲實際上不相等的相等值,那麼您必須聲明(a)接受相等的標準,以及b)拒絕平等的標準。當這些標準被陳述時,那麼人們可能會給你提供關於實施滿足這兩個標準的測試的建議。請注意,(b)和(a)一樣重要,因爲您通常不希望接受實際上不相等的相同值。由於您的計算中存在錯誤,因此某些決策將是錯誤的,您必須確定標準(a)和(b),以便您的應用程序可以接受錯誤的決策。重要的是(a)和(b)不重疊,否則會出現無法做出任何決定的情況。

就你而言,除了從文件讀取數據外,你沒有說明錯誤的來源。如果文件中的數據是由優秀軟件編寫的浮點計算的結果(它能夠以足夠的精度正確地將浮點值轉換爲十進制數字),並且您可以使用優秀的軟件(它能正確地將十進制數字轉換爲浮點數字)點數值),那麼在這個數據的往返中沒有錯誤,並且您應該簡單地測試沒有裝飾的平等。

0

好吧,基於運營商==()爲元組的STL實現我創造了這個,這讓我使用任何比較功能我想對於某些類型:

template<class T> 
bool 
tupleEqualHelper (const T& lhs, const T& rhs) 
{ 
    return lhs == rhs; 
} 

template<> 
bool tupleEqualHelper<double> (const double& lhs, const double& rhs) 
{ 
return return (fabs (lhs - rhs) < (std::numeric_limits<double>::epsilon() * 100)); 
} 

template<counter_t i, counter_t j, class T> 
struct compareHelper; 

template<counter_t i, counter_t j, class T> 
struct compareHelper 
{ 
    static bool tupleEqual (const T& lhs, const T & rhs) 
    { 
    return tupleEqualHelper (std::get<i > (lhs), std::get<i > (rhs)) && 
      compareHelper < i + 1, j, T>::tupleEqual (lhs, rhs); 
    } 
}; 

template<counter_t i, class T> 
struct compareHelper<i, i, T> 
{ 
    static bool tupleEqual (const T&, const T&) 
    { 
    return true; 
    } 
}; 

template<class ... TTypes> 
bool 
compareTuple (const std::tuple<TTypes...>& lhs, const std::tuple<TTypes...>& rhs) 
{ 
    typedef std::tuple < TTypes...> Tp; 

    return compareHelper < 0, std::tuple_size<Tp>::value, Tp>::tupleEqual (lhs, rhs); 
}