3

sscanf を使用してテキスト ファイルからいくつかの値を読み取り、%lf を使用してそれらを double に保存しています。

ただし、値は四捨五入されています。例えば

読み取られるもの: 5.655035220-E02 格納されるもの: 0.0565504

フォーマット指定子「%lf」と関係があると思います。

値をそのまま読み込んで保存するための適切なフォーマット指定子を提案してください。

4

4 に答える 4

3

あなたは次のようなコードを書いたことを意味します (次回はコードを提供していただきありがとうございます。あいまいな手がかりに頼るよりも、何が起こっているのかを理解するのに本当に役立ちます):

#include <stdio.h>

int main(){
  double v2;
  sscanf("5.655035220e-02", "%lf", &v2);
  printf("%f\n", v2);
  return 0;
}

そして、次のような結果が得られます。

0.056550

(10 進数を指定または取得します。)

あなたの問題は、 の 10 進数から 2sscanf()進数への変換ではなく、 の 2 進数から 10 進数への変換にありprintf()ます。変数v2には、スキャンした数値の適切な近似値が含まれています。printf()この概算の多くの桁を印刷するように要求していないだけです。試す:

printf("%.10f\n", v2);
0.0565503522
于 2013-05-30T12:23:16.740 に答える
1

2 つの問題があります

指定子printf()が多すぎるビットを四捨五入しています
(おそらく) 浮動小数点変数は、必要な精度をすべて保持できません。

推奨フォーマット指定子:
読み取り:sscanf(buffer, "%le", &d)
保存:printf("%.*le", DECIMAL_DIG /* or DBL_DIG+3 */, d)


問題1

double d;
sscanf("5.655035220e-02", "%lf", &d);
printf("%.7lf\n", d);  // 0.0565504
printf("%.7le\n", d);  // 5.6550352e-02
printf("%.9le\n", d);  // 5.655035220e-02

を使用して印刷した場合、先頭のゼロ桁%eではなく、より重要な数値になります。%f表示される数値は四捨五入された値です。5.65503522000000008...e-02だった保存番号ではありません


問題 2

floatではなく型を使用していた場合、典型的な 4 バイト浮動小数点doubleの場合と同様に、精度が失われる可能性があります5.655035220e-025.65503537...e-02


What Every Computer Scientist Should Know About Floating-Point Arithmeticを読むことについて、上記の @devnull のアイデアをお勧めします。 http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

于 2013-06-02T02:16:24.740 に答える