等式将此值生成为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
答案 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} }}