2017-07-08 36 views
0

已更新 我正在清理這篇文章後的決議。總而言之,我正在爲Excel計算出下一個最高質數(=NextHighestPrimeNumber(100)返回101)併爲用戶定義的公式。在我開始試驗時,我注意到這個公式在21億左右會出錯。我認爲它可能已經連接到我的變量,所以我嘗試了DOUBLE,但我仍然收到錯誤。MOD函數在Excel中獨家使用長變量VBA

下面是函數:

Function NextHighestPrimeNumber(StartingNumber As Double) As Variant 
Dim CeilingTest As Long 
Dim i As Long 

If StartingNumber < 11 Then 
      If StartingNumber > 6 Then 
       NextHighestPrimeNumber = 11 

      ElseIf StartingNumber > 4 Then 
       NextHighestPrimeNumber = 7 

      ElseIf StartingNumber > 2 Then 
       NextHighestPrimeNumber = 5 

      ElseIf StartingNumber > 0 Then 
       NextHighestPrimeNumber = 3 

      ElseIf StartingNumber = 0 Then 
       NextHighestPrimeNumber = 1 

      Else 
       NextHighestPrimeNumber = "Pick A Positive Integer" 

      End If 

     Exit Function 

Else 

    'Create Array 
    ReDim Prime_Array(0 To 4) As Double 
    GoTo StartArrayPopulate 
DoneWithStartingArray: 

    If StartingNumber Mod 2 = 0 Then 
     StartingNumber = StartingNumber - 1 
    End If 

NewNumber: 
     StartingNumber = StartingNumber + 2 
     CeilingTest = Int(VBA.Sqr(StartingNumber)) 


    'Array loop 
    For i = LBound(Prime_Array) To UBound(Prime_Array) 
     If Prime_Array(i) > CeilingTest Then 
      NextHighestPrimeNumber = StartingNumber 
      Exit Function 
     ElseIf StartingNumber Mod Prime_Array(i) = 0 Then GoTo NewNumber 

     End If 
    Next i 


    'Add new Array Value 
ExpandDim: 
    ReDim Preserve Prime_Array(UBound(Prime_Array) + 1) 
    Prime_Array(UBound(Prime_Array)) = NextHighestPrimeNumber(Prime_Array(UBound(Prime_Array) - 1)) 

    'test if bigger than cieling 
    If Prime_Array(UBound(Prime_Array)) > CeilingTest Then 
     NextHighestPrimeNumber = StartingNumber 
     Exit Function 

    ElseIf StartingNumber Mod Prime_Array(UBound(Prime_Array)) = 0 Then GoTo NewNumber 


    Else 
     GoTo ExpandDim 
    End If 

End If 


Exit Function 

StartArrayPopulate: 


Prime_Array(0) = 3 
Prime_Array(1) = 5 
Prime_Array(2) = 7 
Prime_Array(3) = 11 
Prime_Array(4) = 13 


GoTo DoneWithStartingArray 

End Function 
+2

* 「LONG變量,它應該有一個範圍達到9,223,372,036,854,775,807」 *這是在** ** VB.net不** ** VBA。在後一種類型中,「長」是4個字節。 –

+1

「長整型爲4字節(32位),範圍從-2,147,483,648到 2,147,483,647。您是從哪裏找到MSDN中的定義?」 [Chip Pearson](https://www.pcreview.co.uk/threads/vba-long-data-type-overflow.959041/) – pnuts

+2

顯然你已經諮詢了VB.NET的參考。請參閱[VBA參考](https://msdn.microsoft.com/zh-cn/library/aa263420(VS.60).aspx)。 – GSerg

回答

1

的問題是,因爲VBA MOD功能分子總是轉換成一個長變量,即使它以前被定義爲雙人或一個硬編碼的數字!

考考你:

MsgBox (2147483647) mod 3 'Maximum Long Value

比。

MsgBox (2147483647 + 1) mod 3'Oh False!

我用INT函數複製MOD計算Numerator -(INT(Numerator /Denominator)*Denominator)但也有很多其他的創造性的方式來避免。即使Evaluate與Excel MOD功能正常工作。

底線:我永遠不會使用MOD對於有可能被超過2億

因爲我的第一篇文章我已經清理了我的代碼顯著任何計算,離開了壞行註釋掉扔用`ZZ標記錯誤而導致失敗代碼:

Function NextHighestPrimeNumber(StartingNumber As Double) As Variant 
Dim CeilingTest As Long 
Dim i As Long 


If StartingNumber < 11 Then 
      If StartingNumber > 6 Then 
       NextHighestPrimeNumber = 11 

      ElseIf StartingNumber > 4 Then 
       NextHighestPrimeNumber = 7 

      ElseIf StartingNumber > 2 Then 
       NextHighestPrimeNumber = 5 

      ElseIf StartingNumber > 0 Then 
       NextHighestPrimeNumber = 3 

      ElseIf StartingNumber = 0 Then 
       NextHighestPrimeNumber = 1 

      Else 
       NextHighestPrimeNumber = "Pick A Positive Integer" 

      End If 

     Exit Function 

Else 

    'Create Array 
    ReDim Prime_Array(0 To 4) As Double 
    GoTo StartArrayPopulate 
DoneWithStartingArray: 

    'zz failed code: If StartingNumber Mod 2 = 0 Then 
    If StartingNumber - (Int(StartingNumber/2) * 2) = 0 Then 
     StartingNumber = StartingNumber - 1 
    End If 

NewNumber: 
     StartingNumber = StartingNumber + 2 
     CeilingTest = INT(VBA.Sqr(StartingNumber)) 


    'Array loop 
    For i = LBound(Prime_Array) To UBound(Prime_Array) 
     If Prime_Array(i) > CeilingTest Then 
      NextHighestPrimeNumber = StartingNumber 
      Exit Function 
     'zz failed code: ElseIf StartingNumber Mod Prime_Array(i) = 0 Then 
GoTo NewNumber 
     ElseIf StartingNumber - (Int(StartingNumber/Prime_Array(i)) * Prime_Array(i)) = 0 Then GoTo NewNumber 
     End If 
    Next i 


    'Add new Array Value 
ExpandDim: 
    ReDim Preserve Prime_Array(UBound(Prime_Array) + 1) 
    Prime_Array(UBound(Prime_Array)) = NextHighestPrimeNumber(Prime_Array(UBound(Prime_Array) - 1)) 

    'test if bigger than ceiling 
    If Prime_Array(UBound(Prime_Array)) > CeilingTest Then 
     NextHighestPrimeNumber = StartingNumber 
     Exit Function 

    'zz failed code: ElseIf StartingNumber Mod Prime_Array(UBound(Prime_Array)) = 0 Then GoTo NewNumber 
    ElseIf StartingNumber - (Int(StartingNumber/Prime_Array(UBound(Prime_Array))) * Prime_Array(UBound(Prime_Array))) = 0 Then GoTo NewNumber 

    Else 
     GoTo ExpandDim 
    End If 

End If 


Exit Function 

StartArrayPopulate: 
Prime_Array(0) = 3 
Prime_Array(1) = 5 
Prime_Array(2) = 7 
Prime_Array(3) = 11 
Prime_Array(4) = 13 

GoTo DoneWithStartingArray 

End Function 
+1

對於VBA7-64,這將顯示* 1 *:'Dim i As LongLong:i = 9123372036854775807:MsgBox i Mod 3' - [Data Type Summary - MSDN VBA](https://msdn.microsoft.com/en-us/VBA /語言參考VBA /物品/數據類型的摘要) –