Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么VBA中的for循环在使用万分之一的边界时会少循环一次?_Vba_Excel_For Loop_Decimal - Fatal编程技术网

为什么VBA中的for循环在使用万分之一的边界时会少循环一次?

为什么VBA中的for循环在使用万分之一的边界时会少循环一次?,vba,excel,for-loop,decimal,Vba,Excel,For Loop,Decimal,在VBA中处理函数时,我注意到有时在测试过程中,当我使用不同的参数运行同一函数时,会得到不同的结果。我写了下面这篇文章试图弄清楚到底发生了什么 当for循环以第千位的边界执行时,它会像我预期的那样,在for语句中循环3次。在这里,即时窗口为我慷慨地打印了一个“3”: 但是,当我将边界和步长减小一个量级时,for循环只执行两次for语句 Const vStart = 0.0001 Const vStep = 0.0001 Const vStop = 0.0003 Sub LoopThru()

在VBA中处理函数时,我注意到有时在测试过程中,当我使用不同的参数运行同一函数时,会得到不同的结果。我写了下面这篇文章试图弄清楚到底发生了什么

for循环
以第千位的边界执行时,它会像我预期的那样,在
for
语句中循环3次。在这里,即时窗口为我慷慨地打印了一个“3”:

但是,当我将边界和步长减小一个量级时,
for循环
只执行两次
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循环
更适合这种情况——事实上,我现在正在重写代码以使用while循环。或循环的条件集
。无论是哪种方式,我都想知道这个问题的最佳解决方案,以及为什么执行的循环数会因这些
循环

的边界大小而不同。原因是可以存储在浮点变量中的精度有限。 要获得完整的解释,你应该阅读David Goldberg在1991年3月出版的《计算调查》上发表的论文《每个计算机科学家都应该知道的浮点算术》

在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
=循环的数组维度

如果显式地将常量声明为“Double”,会发生什么?我认为在循环中从隐式初始化类型到双精度类型的强制转换或舍入可能会在某个地方出错。使用
for
循环出现问题的原因是浮点精度(或缺少精度)。我需要一个解释。您需要为循环计数器使用
Long
类型。@八位专家,我尝试将常量声明为
Doubles
,但没有效果@chris,我还试图将循环计数器(
myVar
)声明为
Long
,但是
Long
变量类型是整数,所以我刚刚得到了一个溢出。“帮助”菜单还使我打开了变量类型
vbDecimal
,我尝试了该类型,但也没有成功。可能缺少一个包?问题的根源是浮点精度,以及由此产生的舍入。您需要将循环计数器重新设置为
Long
更改为其他浮点数据类型并不能解决根本问题。如果你需要这方面的帮助,请在Q中添加更多细节。
For i = LBound(YourArray, n) to UBound(YourArray, n)