加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – VBA调试器精度

发布时间:2020-12-16 07:11:21 所属栏目:百科 来源:网络整理
导读:我有一个我相信C等价物是在Excel工作簿模块中的VBA浮点数.无论如何,当我在VBA上设置断点时,我最初分配的值(876.34497)在立即窗口中舍入到876.345,并观察和悬停工具提示.但是,如果我将此Single传递给C DLL,则将其报告为原始值876.34497. 那么,它实际上是作为
我有一个我相信C等价物是在Excel工作簿模块中的VBA浮点数.无论如何,当我在VBA上设置断点时,我最初分配的值(876.34497)在立即窗口中舍入到876.345,并观察和悬停工具提示.但是,如果我将此Single传递给C DLL,则将其报告为原始值876.34497.

那么,它实际上是作为原始值存储在内存中吗?这是调试器的一些限制吗?不确定这里发生了什么.难以测试我传递的是我在C方面得到的东西.

我试过了:

?CStr(test)
876.345
?CDbl(test)
 876.344970703125 
?CSng(test)
 876.345

VBA不是很简单,所以在某种程度上它必须在内存中存储为876.34497.否则,我不认为CDbl会像它一样正确.

解决方法

“单一”类型的VBA变量存储为“IEEE 754 [ – ] 1985 [原文如此]的32位硬件实现”. [见: https://msdn.microsoft.com/en-us/library/ee177324.aspx].

这意味着英语是什么,“单个”精度数字被转换为二进制,然后被截断以适合4字节(32位)序列.维基百科在http://en.wikipedia.org/wiki/Single-precision_floating-point_format年对确切过程进行了详细描述.结果是所有单精度数表示为

(1) a 23 bit "fraction" between 0 and 1,*times*
(2) an 8-bit exponent which represents a multiplier between 2^(-127) and 2^128,*times*
(3) one more bit for positive or negative.

将数字转换为二进制和后退的过程会导致两种类型的舍入错误:

(1)重要数字 – 正如您所注意到的,有效数字有限制. 22位整数只能有8,388,607个唯一值.换句话说,没有数字可以用大于/ – 0.000012%的精度表示.回到高中科学,你可能还记得,这是另一种说法,你不能指望超过六位有效数字(好吧,十进制数字,至少…当然你有22个有效的二进制数字).因此,任何具有超过六位有效数字的数字的表示都将四舍五入.但是,它不会四舍五入到最接近的十进制数字……它将四舍五入到最接近的二进制数字.这通常会导致一些意想不到的结果(比如你的).

(2)二进制转换 – 另一种类型的错误甚至更有害.有一些数字显着少于六位(十进制)数字将被四舍五入.例如,十进制中的1/5是0.2000000.它永远不会“圆润”.但二进制中的相同数字是0.00110011001100110011 ….永远重复. (该序列相当于1/8 1/16 1/16 *(1/8 1/16)1/256 *(1/8 1/16)…)如果您使用任意数量的二进制数字来代表0.20,然后将其转换回小数,你永远不会得到0.20.例如,如果你使用了8位,那么二进制就有0.00110011,它是:

0.12500000
  0.06250000
  0.00781250
+ 0.00390625
------------
  0.19921875

无论你使用多少二进制数字,你都永远不会得到0.20,因为0.20不能表示为2的幂的总和.

简而言之,这解释了发生了什么.当您将876.34497分配给“test”时,它会在内部转换为:

1 10001000 0110110001011000010011
     136       5,969,427

这是(1)* 2 ^(136-127)*(5,427)/(2 ^ 23)

Excel会自动截断单精度数字的显示,仅显示六位有效数字,因为它知道第七位数字可能有误.我无法告诉你这个数字究竟是什么因为我的excel没有显示足够的有效数字!但你明白了.

当您将值强制转换为双精度时,它使用整个二进制字符串,然后在末尾添加另外4个字节的零值.它现在允许您显示两倍的有效数字,因为它是双精度,但正如您所看到的,从8位十进制数字到23位二进制数字的转换然后附加另一个长字符串零引入了一些错误.如果您了解它正在做什么,那不是错误;只是文物.毕竟,它正在完成你告诉它要做的事情……你只是不知道你告诉它做什么!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读