3

10進値になる数値計算を実行するVBAマクロを実行すると、返される結果が正しくない場合があります。

次にいくつかの例を示します。

Dim me_wrong as Double
me_wrong = 1000 - 999.59

結果=0.409999999999968

Dim me_wrong_too as Double
me_wrong_too = 301.84 - 301

結果=0.839999999999975

私はこれまでこれに気づいたことがありません。一体何が起こっているのか?

Office 97に関する次の記事を見ましたが、Excel 2007のバグについては何も見つかりません: http ://support.microsoft.com/default.aspx?scid = kb; en-us; 165373

それに、なぜ私が今まで見たことがないのか説明していません。

助けてください!

4

2 に答える 2

3

Office 97とVBAの問題の説明は、Excel 2007でも同様に適用できます。コアVBAシステムは、後のバージョンに移行してもほとんど変更されていないため、古いVBAマクロを悩ませているのと同じ種類の精度のグレムリンが存続します。

基本的な問題は、2進数での小数の表現に固有の不正確さ、およびその不正確さを軽減するための少なくともいくつかの努力がIEEE浮動小数点表現で行われたことにあります。この場所では、IEEE表現の主題について非常に適切な扱いがあります。

*編集:詳細については、ほんの少しの追加情報をご覧ください。*

些細なケースでこの問題を説明する非常に単純な例として、小数が2の逆乗の合計として表される状況を考えてみます(例:2 -1、2 -2、2 -3など。その結果、.5、.25、.125などのようになります。あなたがそれらの数字を正確に表現しているのであれば、すべてが良いです。ただし、.761のような数値を検討してください。2 -1 +2 -2では.750になりますが、今は.011が必要です。2 -3(.125)は大きすぎますが、2 -4(.0625)は小さすぎます...したがって、2の累乗を続けて、数値を正確に表すことは決してできないことに気づきます。

選択は、解決を停止し、解決/モデリングしている問題に対して「十分に良い」ものとして固有の不正確さを受け入れる場所になります。

于 2012-10-01T20:36:40.287 に答える
1

残念ながら、これはバグではありません。

二重表現は固定小数点表記に従います。仮数は数値「1、x」であり、「1」は暗黙的です。指数と符号があり、基数2で完全に表現されます。

関連する問題はBase=2で、これにより「1、x」の「x」が有限精度(53ビット)の小数バイナリになります。x = a52 * 1/2 + a51 * 1/4 + a50 * 1/8 + ... + a * 1 ** 1 /(2 ^ 52)+ a0 * 1 /(2 ^ 53)と考えてください。ここで、 <i>は仮数のビットです。

この表現で1,4を達成してみてください。そうすれば、精度の壁にぶつかります...バイナリの重みで0.4の有限分解はありません。したがって、標準では、実際の数値の直前の数値を表す必要があると指定されています。これにより、0,39999..9997346(または末尾が何であれ)が残ります。

「良い」ニュースは、先週そのテーマで4つの「c」コーディング日を燃やしたところです。非常に小さいスケール(たとえば10 ^ -9)を使用して数値を表す場合は、Doublesなしで実行できます。非常に大きな変数(long64)で、整数のみを使用して表示関数を実行します(整数除算とその余りを使用して、整数部分と小数部分を数学的に切り取ります)。御馳走、私はあなたに言います...そうではありません。

于 2012-10-01T21:08:02.377 に答える