2016-04-09 9 views
-2

だから、私は0.0Xの範囲の値を比較する必要があると私は、この小さなことでたとえば50.21をスキャン場合値が異なっている

scanf("%f",bill); 

値に格納されているこのプログラムを持っていますvar。法案は実際には50.2099990845 ...後でプログラムで計算を混乱させる。この番号を50.210000にする方法はありますか?御時間ありがとうございます。 (ビジネス・ルールが懸念している限り)

+1

いいえ、通常の理由からです。 50.21は正確に表現できません。たぶん固定小数点演算を使用できますか? – harold

+1

'scanf("%f "、&bill);'、住所演算子か 'bill'はポインタですか?) –

+2

' 1/3'が小数点で表され、ポイントが '0.333 'であることがわかります。 .. 1/100'と同じことをします。これは正確な小数点で表される値を2進浮動小数点に変換するときの問題です。 (整数、0.5、0.25、0.125などの倍数)が動作する特別なケースですが、一般的には実行できませんが、バイナリ浮動小数点表現が適合する最も近い近似を受け入れる必要があります – Steve314

答えて

0

は、IEEE-754浮動小数点数のすべての桁が同じように重要である小数の計算のために(singlefloatdouble)を使用しないでください。これは、IEEE-754に丸め誤差があり、正確な小数を表すことができないためです。これは、少量の情報損失が許容される科学的および工学的なアプリケーションのためのものです。

固定精度の10進数(通貨の値など)を扱う場合は、事前に乗算された整数を使用することをお勧めします。100(100セントの場合)は1ドルを表します。あなたがscanfを使用するつもりなら

、私はこれをお勧めします。

int dollars = 0, cents = 0; 
bool done = false; 
while(!done) { 
    done = scanf("%4d.%2d", &dollars, &cents) != 2 
} 

cents += dollars * 100; 

scanfにバッファオーバーランを防止するために、最大長指定子(それぞれ42)の私の使用を注意してください。

+0

フロートをベースにしたコード全体を書いてしまう前に、私はこのアイデアを打ちたいと思っています。:D – Erik

+0

'... scanf("%4d。%2d "、&dollar、&centents)!= 2 ...セント+ドル= 100円; 'ドル<0 'のときに失敗する。より良い:'セント=ドル* 100 +記号(ドル)*セント; – chux

0

Cのフロート(および他のほとんどの言語)は、IEEE-754表現として格納されます。これらは、科学的な表記法で数字の基本2近似と考えることができます。

.21は2の倍数ではないため、50.21は2進数では正確に表現できないため、ソフトウェアは50.2099990845に丸めて最適化します。

金融アプリケーションでは、ドル(またはそれに相当する金額)ではなく、セントで金額を格納するほうがよいでしょう。この方法では、途中で丸め誤差が発生することはありません。

関連する問題