VBA Val功能改变价值?

时间:2017-06-07 20:27:09

标签: 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结果与雅虎财务计算值相匹配。
这并不是一个实质性的差异,但很好理解为什么以及如何使其与公式验证相匹配。

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

2 个答案:

答案 0 :(得分:5)

考虑一下这个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

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

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

0100000001000000000001010101110000100110010010010011010110101110
0100000001000000000001010101110000100110010010010011010110101011
'                                                            ^^^

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

现在考虑Val Function

  

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

返回

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

作为结论,当精度对计算中的最后一位很重要时,不要对数字应用Val。即使您不知道您的初始变体是双精度型还是字符串,请使用CDbl,这在两种情况下均可正常工作。

答案 1 :(得分:1)

CDbl功能与您的区域设置有关。 Val功能与美国区域设置相关。

如果您在本地区域设置中为Val函数提供值,则会将其解释为美国格式(小数点分隔符的句点,千位分隔符的逗号等)。

我的电脑设置为EN-AU设置(类似于EN-US设置),Val(36.0418746812314) = 36.0418746812314返回True,或者在您的语法中Val(36.0418746812314) <> 36.0418746812314返回{{1} }}