2016-07-17 6 views
-2

ベクトルからスカラーを減算し、その結果をベクトルで返すテンプレート演算子関数を作成しようとしています。以下の機能は、私が思い付くことができたものです:ベクトルからスカラー(フロート)を引くしようとするとC++のテンプレート演算子が、ベクトルからスカラーを減算するときに間違った結果を返す

// vector - scalar 
template<typename T1, typename T2> 
auto operator - (const Vector<T1> & lhs, const T2 & scalar)-> Vector<std::common_type_t<T1,T2>> 
{ 
    using T3 = std::common_type_t<T1, T2>; 
    Vector<T3> result; 
    result.base.reserve(lhs.base.size()); 
    std::transform(lhs.base.begin(), lhs.base.end(), std::back_inserter(result.base), 
      [&scalar](const T3 & element) { return element - scalar; }); 
    return result; 
} 

しかし、結果が正しくない(INT)。オペランドが通常の算術変換積分プロモーションを含む)を受けているため、この問題は疑わしいです。

DEMO

+1

「正しくない」、「間違った結果」は、有用な問題の説明ではありません。 'std :: vector 'と 'float'スカラーを使って' std :: vector 'という結果が得られます。再現できません。 "間違った結果"を定義する。 –

+0

@Sam Varshavchik、デモの目的は、問題を再現することでした。とにかく、この例は次のようになります。v - s =(1,2,3) - 2.1 =(-1.1、-0.0999999、0.9)です。正しい結果はベクトル[-1.1f、-0.1f、0.9f]です。私が困惑するのは、2番目の要素が-0.0999999で、他の要素が正しいということです。 – bobster

+1

いいえ、これらの結果は正しいです。あなたが欠けているのは、[浮動小数点数は正確ではなく、C++や最新のプログラミング言語では決して正確ではありませんでした](http://stackoverflow.com/questions/588004/is-floating-point-math) -壊れた)。 –

答えて

1

これはなく、浮動小数点数は正確ではないという事実と、テンプレートとは何の関係もありません。自分でこれをコンパイルし、結果が何であるかを見るために

float subtract(float a, float b) 
{ 
    return a-b; 
} 

int main() 
{ 
    std::cout << subtract(2, 2.1) << std::endl; 

    return 0; 
} 

試してみてください。

これは、同じ「間違った結果」あなたが具体的なコメントで引用を生成します。

また、-0.0999999です。

浮動小数点演算の素晴らしい世界へようこそ。

正確な固定精度の計算が必要な場合は、それを実装する特殊ライブラリがあります。

+0

あなたは正しいです、テンプレートとは関係ありません。C/C++浮動小数点演算は正確ではありません。私は同等の演算子でBruce Dawson(https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/)の "AlmostEqual2sComplement"メソッドを使用しようとしました。まだ少し微調整が必​​要です。 – bobster

関連する問題