-1

重複の可能性:
float と float リテラルを比較した奇妙な出力

したがって、プログラムは一連の数値を読み取り、入力された合計数値で割ることによってその平均を求めます。ただし、最終結果には最後にさらにいくつかの小数が追加されますが、なぜそれが行われるのかわかりません。

この入力の場合: 483, 10, 3051, 188, 200, 0

出力は 786.4 のはずですが、代わりに 786.400024 です。私は何を間違っていますか?よろしくお願いします。

int main(int argc, char** argv)
{
    int averageOfNumbers = 0;

    printf("Enter the sequence of numbers:");
    int nextNumber;
    float numberCounter = 0;
    do
    {
            scanf("%d", &nextNumber);
            if(nextNumber > 0)
            {
                    numberCounter++;
                    averageOfNumbers += nextNumber;
            }
    } 
    while(nextNumber > 0);
    float finalAverage = (float) (averageOfNumbers/numberCounter);
    averageOfNumbers = averageOfNumbers/numberCounter;
    printf("Average of the numbers in the sequence is %f\n", finalAverage);

}

4

3 に答える 3

3

浮動小数点数は正確ですが、不正確な実数の近似値を提供します。(精度はサイズによって異なります。使用している浮動小数点型で使用できる精度のビット数。)

IEEE 754 浮動小数点 (多くのコンピューターで使用される非常に一般的な表現) では、バイナリが使用されます。これは、1/2、1/4、1/8、およびそれらの組み合わせ (3/8、5/16 など) などの 2 進数の小数が正確に表現されることを意味します (利用可能な精度のビット数の制限内で)。2 の累乗に基づかない分数は、正確には表現できません。

数値 1/10 または 0.1 には正確な表現がありません。マシンに 0.1 を入力すると、0.1 に近い 2 進数の多い値に変換されます。printfこれをまたは何を持っているかを印刷すると、関数がそれを丸め、正確に表現されているように見える0.1ため、再び得られます。と実際の値の差を確認するには 10 進数で 10 桁の精度が必要ですが、8 桁までしか印刷していないとします。もちろん、 と表示されます。浮動小数点印刷ルーチンがエラーを切り落としました!printf0.10.10.10.10.1

C の printfの%f変換指定子は、小数点以下の固定桁数 (デフォルトは 6) を使用するため、大きな数値にはより多くの桁数を使用します。たとえば、0.002 は 0.002000 として出力されます。ただし、数値 123456 は 123456.000000 として出力されます。数値が大きいほど、より重要な数値が出力されます。%f で 786.4 を出力すると、実際には 10 進数で 9 桁の精度が求められます。786 整数部分に 3 つ、さらに 6 つ。

floatおそらく32ビットのIEEE 754 floatを使用しています。これは 24 ビットの精度しかありません。(符号には 1 ビットが使用され、2 進指数には 7 が使用され、24 が残ります。) 24 ビットは、10 進数で約 7 桁の精度に相当します!

つまり、マシンに 786.4 (不正確な表現があることを思い出してください!) を 9 桁まで出力するように要求しています。そこにないさらに2桁の精度を求めているため、2桁のエラーが発生します。

したがって、できることは、より広いタイプのようなものを使用しdoubleたり、結果を印刷する方法を変更したりすることです。多くの有効数字を求めないでください。たとえば、%.3f(小数点以下 3 桁) を試してください。

ちなみに、Cのfloat型はめったに使用されません。通常は type で作業したいと考えていdoubleます。float大きな配列でスペースを節約するなどの用途があります。

于 2012-04-09T07:33:02.813 に答える
0

double を使用すると、問題が解決します。フロートの正確さと精度が問題の原因です。

于 2012-04-09T07:32:37.683 に答える
0

浮動小数点型は、すべての数値を完全な精度で表すことはできません。多くの数値は、浮動小数点で近似的にしか表すことができません。これは、十分な有効桁数が与えられると、表現にうまく収まらない数値の精度が最終的に失われることを意味します。

floatデータ型を使用する際の問題は、浮動小数点型の中で最も精度が低いことです。(C および C++ のデフォルトの浮動小数点型はdoubleであり、これを使用する必要があります。float を使用するやむを得ない理由がない限り、 floatの使用は避ける必要があります)。最新の 32 ビット デスクトップ プラットフォームでは、floatは近似値の有効数字が約 6 ~ 7 桁までしか正確ではない場合があります。有効数字であり、小数点以下ではありません!)。

浮動小数点数がどのように機能するかを読む時間を費やすことを強くお勧めします (Google に入力すると、たくさんの説明が見つかります!) ; それらが内部でどのように表現されているかを理解することは、より優れたプログラマーになるのに役立ちます

于 2012-04-09T07:36:11.750 に答える