-2

印刷出力用に、システム精度の浮動小数点数を指定された精度 (たとえば、小数点以下 3 桁) の浮動小数点数に変換する必要があります。fprintf 関数は、一部の数値を正しく丸めないため、これには十分ではありません。私が試した他のすべてのソリューションは、浮動小数点数に戻すときに望ましくない精度を再導入するという点で失敗します。例えば:

float xf_round1_f(float input, int prec) {

    printf("%f\t",input);
    int trunc = round(input * pow(10, prec));
    printf("%f\t",(float)trunc);
    input=(float)trunc / pow(10, prec);
    printf("%f\n",input);
    return (input);

}

この関数は、入力、切り捨てられた整数、および出力を各行に出力します。結果は、小数点以下 3 桁に切り捨てられるはずの数値の場合、次のようになります。

49.975002 49975.000000 49.974998

49.980000 49980.000000 49.980000

49.985001 49985.000000 49.985001

49.990002 49990.000000 49.990002

49.995003 49995.000000 49.994999

50.000000 50000.000000 50.000000

「trunc」が印刷用に浮動小数点にキャストされている場合でも、2 番目のステップが意図したとおりに機能することがわかりますが、浮動小数点数に変換するとすぐに精度が戻ります。1 行目と 6 行目は、問題のケースを示しています。

確かにこれを解決する方法があるに違いありません.1行目の結果が49.975002のままだったとしても、フォーマットされた印刷は望ましい効果をもたらしますが、この場合は本当の問題があります.

解決策はありますか?

4

4 に答える 4

1

すべての小数を小数点以下 3 桁で正確に表現する必要がある場合は、1000 分の 1 で作業できます。整数データ型を使用して、すべての中間結果の実際の数の 1000 倍を表します。

于 2013-10-02T19:29:12.523 に答える
0

固定小数点数。これは、実際の数値を long や long long などの広精度整数形式で保持する場所です。また、小数点以下の桁数も保持します。次に、固定小数点数を小数点以下の桁数でスケーリングするメソッドも必要になります。そして、文字列との間で変換するいくつかの方法。

1/10 が 2 の分数の累乗 (1/2、1/4、1/8 など) として正確に表現できないという問題が発生している理由。これは、1/3 が基数 10 の繰り返し小数 (0.33333...) であるのと同じ理由です。

于 2013-10-03T07:48:23.957 に答える