9

この C プログラムが「間違った」出力を出すのはなぜですか?

#include<stdio.h>

void main()
{
    float f = 12345.054321;

    printf("%f", f);

    getch();
}

出力:

12345.054688

しかし、出力は12345.054321.

VS2008 で VC++ を使用しています。

4

5 に答える 5

11

すべての実数値が float (または double) で表現できるわけではないという理由だけで、「間違った」答えを出しているのです。得られるのは、基になるエンコーディングに基づく概算です。

1.0x10 -100から 1.1x10 -100 (非常に小さい範囲) の間であっても、すべての実数値を表すには、依然として無限のビット数が必要です。

単精度の IEEE754 値は 32 ビットしか使用できないため (そのうちのいくつかは、指数や NaN/Inf 表現などの他のものに割り当てられます)、無限の精度を与えることはできません。実際には 23 ビットが利用可能で、精度は約 2 24 (追加の暗黙のビットがあります) または 7 桁をわずかに上回ります (log 10 (2 24 ) はおよそ 7.2 です)。

実際には間違っていないので、「間違っている」という言葉を引用符で囲みます。間違っているのは、コンピューターが数値を表す方法についてのあなたの理解です (ただし、気分を害しないでください。この誤解をしているのはあなただけではありません)。

http://www.h-schmidt.net/FloatApplet/IEEE754.htmlにアクセスし、「10 進表現」ボックスに数値を入力して、実際の動作を確認してください。

より正確な数値が必要な場合は、float の代わりに double を使用します。これらは、値を表すために使用できるビット数が 2 倍になります (C 実装が、float と double にそれぞれ IEEE754 の単精度と倍精度のデータ型を使用していると仮定します)。

任意の精度が必要な場合は、GMPなどの「bignum」ライブラリを使用する必要がありますが、これはネイティブ型よりもやや遅いため、トレードオフを理解していることを確認してください。

于 2010-05-11T06:29:15.733 に答える
2

float10 進数の 12345.054321 は、お使いのプラットフォームでは正確に表すことができません。表示されている結果は、 として表すことができる最も近い数値の 10 進近似floatです。

于 2010-05-11T06:28:43.410 に答える
2

floats は利便性と速度に関するものであり、2 進数表現を使用します。精度を気にする場合は、10 進数型を使用します。

この問題を理解するには、What Every Computer Scientist Should Know About Floating-Point Arithmeticを読んでください: http://docs.sun.com/source/806-3568/ncg_goldberg.html

解決策については、10 進数の算術 FAQを参照してください: http://speleotrove.com/decimal/decifaq.html

于 2010-05-11T06:32:41.827 に答える
1

それはすべて精度に関係しています。数値を float に正確に格納することはできません。

于 2010-05-11T06:30:46.517 に答える
0

単精度浮動小数点値は、約 8 ~ 9 桁の有効 (10 進数) 桁しか表すことができません。そのポイントを超えると、量子化エラーが発生します。

于 2010-05-11T06:30:26.057 に答える