MOD函数在Excel VBA中独占使用长variables

已更新我正在清理这个职位后的决议。 总之,我正在为Excel计算下一个最高质数( =NextHighestPrimeNumber(100)返回101 )的用户定义公式。 当我开始试验时,我注意到这个公式在21亿左右会出错。 我以为它可能已经连接到我的variables,所以我尝试了DOUBLE,但我仍然收到错误。

这是function:

 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 

问题是因为VBA MOD函数总是将分子转换为LONGvariables,即使它以前被定义为Double或是一个硬编码的数字!

testing自己:

MsgBox (2147483647) mod 3 'Maximum Long Value

比。

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

我使用INT函数来复制mod计算Numerator -(INT(Numerator /Denominator)*Denominator)但还有很多其他的创造性的方法可以避免。 即使用excel MODfunctionEvaluate能正常工作。

底线: 我决不会使用MOD进行任何可能超过20亿的计算

自从我的第一篇文章,我已经清理了我的代码,并留下不良的行注释,抛出错误标记为`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