VBA Val功能改变价值?

NOY*_*OYB 2 vba

等式将该值产生为Variant/Double X:36.0418746812314

但是:
X <> Val(X)为真
X <> CStr(X)为假
X <> CDdl(X)为假

Val()如何改变价值?
当在监视列表中查看时,应用X = Val(X)似乎不会改变X的值或类型.但不知何故它是不同的.

例如:
A = X - Val(X)非常小,但不是零(2.1316282072803E-14).
B = X - CStr(X)非常小,但不是零(2.1316282072803E-14).
C = X-CDbl(X)为零.

更新:感谢大家的回复和答复.这是一些额外的背景.

股息调整后收盘价的公式.据称雅虎财经使用.
A1 = A0 + A0*(((P1/S) - P0 - D)/ P0)

拆分和股息调整收盘价格
股票代号:INTC
日期:1980年8月29日星期五
0.306757021582758(雅虎财务计算)
0.306757021582704(我的VBA计算)

将A1转换为字符串CStr(A1)或应用Val(A1),然后我的VBA结果与Yahoo Finance计算值匹配.
这并不是一个实质性的差异,但很好理解为什么以及如何使其与公式验证的目的相匹配.

公式来源,组件详细信息和说明.
"雅虎如何计算调整后的收盘价"
http://marubozu.blogspot.com/2006/09/how-yahoo-calculates-adjusted-closing.html

A.S*_*S.H 6

考虑一下这个MCVE:

Sub TestingVal()
  Dim x As Double, y As Double
  x = 36.0418746812314 + 2.1316282072803E-14
  y = Val(x)
  Debug.Print x, y, x <> y       ' 36.0418746812314  36.0418746812314  True
End Sub
Run Code Online (Sandbox Code Playgroud)

X和Y两个显示相同的方式,由于显示精度.但它们的实际值(二进制表示)是不同的.

有关信息,以下是IEEE-754格式中x和y的二进制表示:

0100000001000000000001010101110000100110010010010011010110101110
0100000001000000000001010101110000100110010010010011010110101011
'                                                            ^^^
Run Code Online (Sandbox Code Playgroud)

只有最后3位(尾数)不同!这个差异不足以显示它们何时以十进制数字显示在基数10中.

现在考虑Val函数:

返回字符串中包含的数字作为适当类型的数值

这意味着,在Val(x)数字中x,首先将数字转换为a String以匹配函数的参数类型.这导致其在Base 10中显示的值.然后Val将其转换回数字并将其存储在中y.由于在第一阶段显示的值不是确切的值,因此我们得到了一些精度x <> Val(x).

作为结论,当精度对计算中的最后一位很重要时,不适Val用于数字.即使你不知道你的初始变体是双重还是字符串,使用CDbl哪种方法在两种情况下都能正常工作.

  • 而且,当然,另一件要警惕的是试图在**任何**等级/不等式比较中使用"Double" - 例如`49*CDbl(1/49)= 1`是'False `由于最后一位的四舍五入.(如果它只是'49*(1/49)= 1`你会得到'真' - 不确定是否是由于优化,或者它是否在中间计算中存储额外的位) (3认同)
  • 为什么不使用`CDec`代替`CDbl`,并保留打印精度?`Debug.Print CDec(36.0418746812314)+ CDec(2.1316282072803E-14)'打印36.041874681231421316282072803` (2认同)