2017-02-16 4 views
0
#include<iostream> 

long myround(float f) 
{ 
    if (f >= UINT_MAX) return f; 
    return f + 0.5f; 
} 

int main() 
{ 
    f = 8388609.0f; 
    std:cout.precision(16); 
    std::cout << myround(f) << std::endl; 
} 

出力四捨五入:私は、出力の意味を理解しようとしている8388610.0フロートがエラー

を。 8388609.0より大きい次の浮動小数点は8388610ですが、なぜ丸められた値が8388609ではないのですか?

+1

_「8388609.0より大きい次の浮動小数点は8388610です」_この結論にどうやって到達しましたか? –

+0

単精度浮動小数点数は、これらの10進数(6以上)のすべての表現を保証するのに十分なスペースがありません。あなたは何をしようとしていますか? –

+0

このコードはコンパイルされません。あなたは 'f'の宣言をしていません。あなたの_actual_ [MCVE]を投稿して、記載された出力につなげてください。 –

答えて

1

IEEE-754ではいくつかの可能な丸めモードが定義されていますが、実際にはほとんどの場合、常に最も近いものが「最も近いものに丸められ、偶数につながる」ものです。これは「バンカーの丸め」とも呼ばれ、誰も識別できない理由はありません。

"Ties to even"は、浮動小数点演算の丸め結果が2つの表現可能な数の間の正確に中間である場合、結果のLSBをどちらの方向にも丸めることを意味します。あなたのケースでは、8388609.5は8388609と8388610の中間にありますが、最後のビットでは後者のみがゼロであるため、四捨五入は上向きです。代わりに8388610.0を渡した場合、結果は下に丸められます。あなたが8388611.0で合格した場合、それは上に丸められます。

+0

あなたの説明をありがとう。私の質問に答えます。また、私は、浮動小数点ハードウェアが、丸め処理の方法を決定すると仮定します。これは、FPハードウェアが実際に正確な値を計算し、丸めポリシーに基づいて表現可能な浮動小数点表現にマップすることを意味しますか? – KodeWarrior

+0

これはFPハードウェアに関する私の質問に答えました。 http://pages.cs.wisc.edu/~markhill/cs354/Fall2008/notes/flpt.apprec.html – KodeWarrior

1

例をdoubleに変更すると、エラーが表示されなくなります。問題は、floatが格納できる有効数字の桁数がdoubleよりも制限されていることです。あなたの値に0.5を加えることは、浮動小数点数の精度限界を単に超えてしまい、何らかの丸めを行うことになります。この場合、8388609.0f + 0.5f == 8388610.0f。あなたの番号に数字を追加していく場合

#include<iostream> 

long myround(double f) 
{ 
    if (f >= UINT_MAX) return f; 
    return f + 0.5; 
} 

int main() 
{ 
    double f = 8388609.0; 
    std::cout.precision(16); 
    std::cout << myround(f) << std::endl; 
} 

、それはまた、最終的にdoubleのために失敗します。

編集: これは簡単にstatic_assertでテストできます。これは私のプラットフォームstatic_assert(8388609.0f + 0.5f == 8388610.0f, "");でコンパイルされます。それはおそらくあなたの上でコンパイルされます。