2012-04-27 21 views
13

誰かがこの動作を説明できますか?私は浮動小数点数の機械レベルの表現をよく知っています。これはprintfとそのフォーマットに関係しているようです。 両方の数値は、浮動小数点表記で正確に表されます(チェック:64を掛けると整数になります)。倍精度のprintf丸め動作

#include <stdio.h> 
#include <iostream> 
using namespace std; 

int main() { 
    double x1=108.765625; 
    printf("%34.30f\n", x1); 
    printf("%9.5f\n", x1); 
    printf("%34.30f\n", x1*64); 

    double x2=108.046875; 
    printf("%34.30lf\n", x2); 
    printf("%9.5f\n", x2); 
    printf("%34.30f\n", x2*64); 
} 

出力:

> 108.765625000000000000000000000000 
> 108.76562 
> 6961.000000000000000000000000000000 
> 108.046875000000000000000000000000 
> 108.04688 
> 6915.000000000000000000000000000000 

メモ、最初の数は切り捨て取得し、2つ目は切り上げます。

+1

私の記事http://www.exploringbinary.com/inconsistent-rounding-of-printed-floating-point-numbers/に興味があります。いくつかの実装では、「半減」の代わりに「ゼロからの半減」を使用します。 –

+0

MicrosoftはVS 2010とVS2015の間でデフォルトの丸め動作を変更したようです。私はちょうど1つから他にアップグレードし、いくつかの非常に迷惑と微妙なバグを持っています。 [このブログ](https://blogs.msdn.microsoft.com/vcblog/2014/06/18/c-runtime-crt-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1 /)はおそらく変更を強調することを意図していますが、あなたはそれを完全に逃したことを許されます。 – omatai

+0

それは実装に依存します。[sprintfのWindowsベースのシステムとUNIXベースのシステムの丸めの違い](http://stackoverflow.com/q/4649554/995714)、[C++ sprintfとの結びつきの丸め動作の整合性](http:// stackoverflow。 com/q/31142600/995714) –

答えて

17

「偶数に丸める」または「バンカーの丸め」です。丸められた表現の最後の桁は、その数が2つの間のちょうど半分であっても選択されます。

http://linuxgazette.net/144/misc/lg/a_question_of_rounding_in_issue_143.html
C99の仕様が言うように銀行が、これは他のいくつかのCライブラリよりも正確である 『ラウンドにも、丸め『または』「GNU Cライブラリの場合は、()のprintfで使用される丸めルールがあります』。小数点への変換は、現在選択されているIEEE丸めモード(デフォルトのバンカー丸め)を使用する必要があります。

+0

:http://www.gnu.org/software/libc/manual/html_node/Rounding.html –

+1

リンク先の記事の著者は無能です。 「バイナリと小数の基数は同じ非合理的な数を共有しません」 - それはナンセンスです。合理性/非合理性は、基盤とは無関係です。 –

+1

@ R ..確かに。しかし、記事の引用符で囲まれた部分は、バグレポート(http://sourceware.org/bugzilla/show_bug.cgi?id=4943)で苦労して学んだように正しいです。 –

0

出力は、ソース番号の最も近い小数点の後に5桁の数字を示します。

関連する問題