2013-12-23 2 views
7

浮動小数点数と整数を以下のように掛け合わせると、すべての乗算が異なる結果につながるのはなぜですか?私の期待は一貫した結果でした。私はどちらの場合も、int値が乗算の前に暗黙的にfloatに変換されると考えました。しかし、違いがあるようです。この異なる扱いの理由は何ですか? int/floatの乗算が異なる結果につながるのはなぜですか?

int multiply(float val, int multiplier) 
{ 
    return val * multiplier; 
} 

int multiply2(float val, int multiplier) 
{ 
    return float(val * multiplier); 
} 

float val = 1.3f; 

int result0 = val * int(10); // 12 
int result1 = 1.3f * int(10); // 13 
int result3 = multiply(1.3f, 10); //12 
int result4 = multiply2(1.3f, 10); // 13 

は、おそらくあなたのために何が起こる

+0

これは実際のコードですか?私は両方に対して同じ結果を得て、なぜそれが違うのか分かりません。 –

+2

2番目の式はコンパイル時に評価できます - どのコンパイラを使用していますか?それが生成するバイトコードを見てください。 – Floris

+0

Ubuntuでg ++ 4.7.3を試してみてください:両方の乗算が13 – gturri

答えて

8

があるあなたに トルステンありがとう:IEEEまたは類似のフロートを想定し

は、1.3が表現できない、そしておそらく10を乗じた1.299999のようなものが12.99999されていますintに切り捨てられた値は12です。

ただし、1.3 * 10はコンパイル時に評価される可能性があり、13の正確な表現になる可能性が最も高くなります。

実際にコードがどのように構成され、どのコンパイラが使用され、どの設定が使用されているかに応じて、実行時にこれを実行するか、コンパイル時に実行するかによって、1から12または13のいずれかを評価できます。

完全にするために、次のコードで、私はそれを再現することができます:

extern int result0; 
extern int result1; 

float val = 1.3f; 

void foo() 
{ 
result0 = val * int(10); // 12 
result1 = 1.3f * int(10); // 13 
} 
+0

コンパイラはコンパイル時の計算に異なる表現を使用できますか? –

+0

@sftrabbit私の推測はそれが実装であると定義されています –

+0

@sftrabbit:標準の見積りは手元にありませんが、それはアフリカです。これは、テンプレートが非型浮動小数点パラメータを許可しない理由の領域にもあります。 – PlasmaHH

関連する問題