double を含む 2 つのタプルをできるだけ効率的に比較したいと考えています。
これは、浮動小数点の精度のために事前定義された operator==(...) を使用して行うことができないため、最善の方法は何ですか? 本当にすべてのタプル要素をループする必要がありますか?それとも、コンパイラが SIMD 最適化を呼び出せるようにするために使用できるテンプレート マジックがありますか?
double を含む 2 つのタプルをできるだけ効率的に比較したいと考えています。
これは、浮動小数点の精度のために事前定義された operator==(...) を使用して行うことができないため、最善の方法は何ですか? 本当にすべてのタプル要素をループする必要がありますか?それとも、コンパイラが SIMD 最適化を呼び出せるようにするために使用できるテンプレート マジックがありますか?
浮動小数点値の等価性の比較が損なわれるというのは誤解です。ひどく壊れていない実装では、浮動小数点値が等しいかどうかを比較すると、比較された値が等しい場合にのみ true が返されます。
実際のエラーは、計算の早い段階にあります。これらのエラーは、制御および特徴付けする必要があります。エラーの特徴を明らかにしないと、目的に合った操作を実行することを推奨することはできません。
不正確に計算された値があり、それらにエラーが含まれている可能性があり、実際には等しくない値を等しい値として受け入れたい場合は、(a) 等しい値を受け入れるための基準、および (b) 基準を述べる必要があります。平等を拒否するために。これらの基準が示されている場合、人々は両方の基準を満たすテストの実装について推奨できる場合があります。(b) は (a) と同様に重要であることに注意してください。これは、通常、実際には等しくない値を等しいと見なしたくないためです。計算に誤りがあるため、決定の一部が間違っている可能性があります。アプリケーションで誤った決定が受け入れられるように、基準 (a) と (b) を決定する必要があります。(a) と (b) が重複しないことが重要です。重複しないと、決定が受け入れられない場合があります。
あなたの場合、ファイルからデータを読み取る以外にエラーの原因はないと述べています。ファイル内のデータが、適切なソフトウェア (十分な精度で浮動小数点値を 10 進数に正しく変換するソフトウェア) によって記述された浮動小数点計算の結果であり、適切なソフトウェア (10 進数を浮動小数点数に正しく変換するソフトウェア) でデータを読み取る場合、ポイント値) の場合、このデータのラウンドトリップにエラーはなく、装飾なしで単純に等しいかどうかをテストする必要があります。
わかりました、タプルの operator== () の 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);
}