Excel 2007 VBA计算错误

当您运行执行数字计算结果为十进制值的VBAmacros时,返回的结果可能不正确。

这里有几个例子:

Dim me_wrong as Double me_wrong = 1000 - 999.59 

RESULT = 0.409999999999968

 Dim me_wrong_too as Double me_wrong_too = 301.84 - 301 

结果= 0.839999999999975

我以前从未注意到这一点。 究竟是怎么回事?

我已经看到下面的文章有关Office 97,但无法find任何有关Excel 2007中的错误: http : //support.microsoft.com/default.aspx?scid= kb;en-us; 165373

再加上它没有解释为什么我从来没有见过它。

请帮忙!

对于Office 97和VBA中的问题的解释同样适用于Excel 2007.尽pipe迁移到了更高版本,但核心VBA系统基本上没有变化,因此与旧VBAmacros相同的准确性gremlins将会持续存在。

基本问题在于二进制小数的表示中固有的不准确性,以及如何用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)太小了…所以你继续使用两个较小的幂,意识到你永远不会 精确地代表数字。

select成为你停止解决的地方,并接受固有的不准确性,因为你正在解决/build模的问题“足够好”。

不幸的是,这不是一个错误。

双重表示遵循固定点符号,其中尾数是数字“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)尾数是位数。

尝试用这种表示达到1,4,并且您击中了精确的墙壁…在二进制权重中没有0.4的有限分解。 所以这个规范指定你应该在真正的数字之前表示这个数字,这会给你留下0,39999..9997346(或者尾巴)。

这个“好”的消息是,上个星期我刚刚烧了4个“c”代码,如果用一个很小的比例 (比如说10 ^ -9)代表你的号码,那么你可以不用双打非常大的variables (long64)中,并使用除整数之外的其他任何东西来显示函数(通过整数除法和剩余部分math地切割整数和小数部分)。 一种享受,我告诉你…不。