2014-01-17 21 views
2

在處理VBA中的函數時,我注意到有時在測試過程中,當我使用不同的參數運行相同的函數時,會得到不同的結果。我寫了下面的小節來試圖弄清楚發生了什麼。爲什麼VBA中的for循環在千分之一的位置使用邊界時會少一點時間?

for-loop以千分位的邊界執行時,它會循環執行for語句三次,就像我期望的那樣。在這裏,立即窗口慷慨地打印出「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 

在我的實際項目中,我創建了一個大的三維數組作爲查找表。由於必須使用Solver生成數組的第一維,因此通過創建此查找表,我將大大減少應用程序的運行時間,而不必在應用程序運行時反覆使用Solver重新計算。

由於它是一個3D數組,因此它有3個嵌套for循環,其中第二個循環的範圍可以從百分之十到十分之一。

也許do-while loop更適合這種情況 - 事實上我現在重寫代碼來使用while循環代替。或有條件的for-loops。無論哪種方式,我想知道這個問題的最佳解決方案,以及爲什麼根據這些for loops中邊界的大小執行的循環數有所不同。

+0

如果你顯式聲明常量「爲雙」,會發生什麼?我正在考慮將隱式初始化類型轉換爲Double或在您的循環中進行Double處理可能會在某處出現跳動。 –

+2

「For'循環出現問題的原因是浮點精確(或缺少)。 [見此](http://stackoverflow.com/a/7330887/445425)的解釋。你將需要使用'長'類型的循環計數器。 –

+0

@ Eight-BitGuru,我嘗試將常量聲明爲'Doubles',但無濟於事。 @chris,我也試圖將循環計數器('myVar')聲明爲'Long',但Long'變量類型是一個整數,所以我剛剛發生溢出。幫助菜單也將我轉向了我嘗試的變量類型'vbDecimal',但這也不起作用。也許一個包丟失了? – marmalar

回答

2

原因是可以存儲在浮點變量中的有限精度。 有關完整的解釋,請閱讀論文「每位計算機科學家應瞭解浮點運算的知識」,David Goldberg在1991年3月號的Computing Surveys雜誌上發表。

Link to paper

在VBA默認浮點類型是雙這是一個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 =陣列空間維度循環

相關問題