VBA Val函数改变值?

标签 vba

一个方程产生这个值作为变体/双 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

最佳答案

考虑这个 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 为基数显示 14 位十进制数字时,这种差异不足以显示出来。

现在考虑 Val Function :

Returns the numbers contained in a string as a numeric value of appropriate type

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

作为结论,当精度对计算的最后一位很重要时,不要应用 Val在一个数字上。即使您不知道您的初始变体是 double 还是字符串,也可以使用 CDbl这在这两种情况下都很有效。

关于VBA Val函数改变值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44422173/

相关文章:

excel - 仅使用 VBA : Error "Unable to get the PasteSpecial property of the Range class 粘贴值

Excel:禁用有关尝试在 BeforeDoubleClick 上更改 protected 单元格的警报

ms-access - 通过更改 Detail.Height 在 MS Access 中调整表单大小

vba - 在不同的工作表中运行宏时出错

vba - 将功能键分配给 excel 宏

VBA Excel - 组合多个自动过滤器

vba - 用户创建的 VBA 函数返回 #VALUE

excel - 如何使用 Excel 在 VBA 中禁用 ListView 控件中的箭头键

vba - 生成所有 2^n 个子集的列表

excel - 提取最后一个反斜杠后剩余字符串的函数