为什么在千分之一的地方使用边界时,VBA循环中的for循环会少一些?

时间:2014-01-17 21:17:47

标签: vba excel-vba for-loop decimal excel

在使用VBA中的函数时,我注意到有时在我的测试中,当我使用不同的参数运行相同的函数时,我会得到不同的结果。我写了下面的子,试图弄清楚发生了什么。

for-loop以千分之一的边界执行时,它会循环遍历for语句3次,正如我所期望的那样。在这里,立即窗口慷慨地为我打印“3”:

Const vStart = 0.001
Const vStep = 0.001
Const vStop = 0.003

Sub LoopThru()
    Dim myVar As Double
    Dim counter As Integer 

    For myVar = vStart To vStop Step vStep
        counter = counter + 1
    Next myVar

    Debug.Print counter
End Sub

但是,当我减小边界并逐步增加幅度时,for-loop只会执行两次for语句。

Const vStart = 0.0001
Const vStep = 0.0001
Const vStop = 0.0003

Sub LoopThru()
    Dim myVar As Double
    Dim counter As Integer

    For myVar = vStart To vStop Step vStep
        counter = counter + 1
    Next myVar

    Debug.Print counter
End Sub

在我的实际项目中,我正在创建一个大的3D数组值作为查找表。由于必须使用Solver生成数组的第一个维度,因此我将通过创建此查找表来大大减少应用程序的运行时间,而不必在应用程序运行时反复使用Solver重新计算。

由于它是一个3D数组,因此有3个嵌套for循环,其中第二个循环可以通过千分之一到十分之一的值。

也许do-while loop更适合这种情况 - 实际上我现在正在重写代码以使用while循环。或者是for-loops的条件集。无论哪种方式,我想知道这个问题的最佳解决方案,以及为什么根据这些for loops中的边界大小执行的循环次数存在差异。

1 个答案:

答案 0 :(得分:2)

原因是可以存储在浮点变量中的有限精度。 为了获得完整的解释,你应该阅读1991年3月出版的计算机调查中发表的论文"每个计算机科学家应该知道的关于浮点算术的内容" ,由David Goldberg发表。

Link to paper

在VBA中,默认浮点类型为Double,即IEEE 64位(8字节)浮点数。

您需要重构代码以使用循环计数器的整数类型。

为了演示转换为整数循环计数器的一种方法,请考虑以下几点:

Const vStart = 0.0001
Const vStep = 0.0001
Const vStop = 0.0003

Sub LoopThru()
    Dim myVar As Double
    Dim counter As Long

    For counter = 0 To (vStop - vStart) * 10000 Step vStep * 10000
        myVar = counter * vStep + vStart
        Debug.Print "Iteration " & counter, "myVar = " & myVar
    Next
End Sub

如何在更广泛的背景下实施将取决于您的具体情况。

由于您提到循环数组,请考虑使用类似

的内容
For i = LBound(YourArray, n) to UBound(YourArray, n)

其中n =要循环的数组维度