2012-03-25 19 views
0

私は職場のフローコンピュータ(PLCのようなもの)からレジスタを読み込んでいます。ドキュメントごとに、レジスタはIEEE単精度浮動小数点数として格納されます。私はレジスタを読み取り、CComVariants(MS VARIANTクラスのラッパー)に格納します。単精度浮動小数点変数を持つ分数を格納する

私はこのような奇妙な後続フラクションと値を表示VS2010でブレークポイントを介して実行を一時停止すると、私は

0.45 
0.3 
0.2 
0.05 

...このような値は、デバイス・レジスタに格納されている知っている...

0.4500000000031 
0.300000034 
0.2000000005 
0.05000000004 

私の質問は、Visual Studio 2010 IDEが不正確であるか、IEEEの単精度浮動小数点数だけがこのアプリケーション(+/- 0.00001)で十分ではないということですか?私はすべてのこれらの画分は、1

答えて

1

浮動小数点精度に合計かどうかを確認するために、これらの値が一定の範囲内にある場合は、後に、コードを参照するためにチェックするコードに配置する必要があるため、私は尋ねる

されます小数点以下の桁数。 シングル/ダブルなどは、格納可能な番号の範囲と、ポイントの後に保持できる個所の数です。

正確な表現が必要な場合は、浮動小数点を使用できません。

小数点型やその他の型(* 100、intなど)に変換してみることもできますし、十分正確なものとしてそのまま使用することもできます。

浮動小数点は、可能なすべての値を表すことができません。ギャップがあります。 ITは10進数で1/3で書いているのと同じ問題です。

0.33333333は近いですが、漸近的です。 addinhg more 3sで1/3に近づくことはできますが、そこには決して行きません。

0

浮動小数点数には一般的に小数は格納されません。通常、単精度浮動小数点数である「浮動小数点数」は、符号、24ビットの2進数(「仮数」)、および数値をスケーリングする8ビットの指数を格納します。符号がs(+1または-1)であり、仮数部がfで指数部がeである場合、格納された浮動小数点はs * f * 2 eを表します。

浮動小数点は、s * f * 2 eが正確に.45であるような符号、仮数、および指数がないため正確に.45を表すことができません。 2のべき乗を整数倍にしたときに、正確に.45に等しい整数は存在しないため、これは精度を変更することはできません。したがって、.45が浮動小数点数に格納されるように準備されている場合は、浮動小数点数が表すことができる最も近い数値に丸めなければなりません。このため、0.4500000000031が表示されます。

私が残したことがいくつかあることに注意してください。これらはおそらくあなたの直面する問題に役立つことはありませんが、完全性のためにそれらを言及します:非定型浮動小数点表現があるかもしれません。最近はまれです。浮動小数点演算のIEEE-754規格の前でより一般的でした。仮数部は24ビットですが、23ビットしか格納されません。先頭のビットは暗黙的に1です。 8ビットの指数は、指数が-126から127の1〜254の区間の数値として格納されます。格納された指数が0の場合、仮数は24ビット未満です。暗黙ビットはゼロであり、指数は-126でクランプされたままである。格納された指数が255の場合、floatは無限大(仮数がゼロの場合)または "not a number"(それ以外の場合)を表します。最新のIEEE-754規格では、10進算術の形式が指定されていますが、すべてのシステムでサポートされているわけではありません。

使用するシステムが小数点演算をサポートしていて、使用するすべての数値が、使用可能な精度の小数として正確に表現できる場合は、正確な答えを得るために使用できます。

小数値演算を使用していない場合は、より一般的な2進浮動小数点演算を使用しますが、丸め誤差は処理されます。ときには、正確に1を加算する数値のリストを持ち、浮動小数点数でそれらを格納し、浮動小数点数を合計すると、正確に1ではない答えが得られます。そして、時には、1に加算されない数(「はい、合計は1ですが、そうではありません」)、偽陰性の結果が生じる可能性があります(「いいえ、合計はありません」 1 "ですが、それです)。偽陽性を犠牲にして偽陰性を拒否することもできます。 (たとえば、合計プロセスでエラーが発生する可能性のある量を計算し、1に近い数値を受け入れることができます。これは、正確に完了した場合は1になるすべての合計を受け入れることになりますが、

これが受け入れられない場合、計算を実行する他の方法があるかもしれません。あなたのすべての数値がn/100の形式を持ち、nが整数の場合、n/100をfloatに格納する代わりにintに格納します。次に、整数を正確に追加することができます。格納された整数の合計が100の場合、正確な合計は1です。

関連する問題