[英]Excel VBA - Using Long Variables inside Range function while filtering
[英]MOD Function Exclusively Uses Long Variables In Excel VBA
更新后,我将清理该帖子。 总而言之,我为excel创建了一个用户定义的公式,该公式计算了下一个最高质数( =NextHighestPrimeNumber(100)
返回101
)。 当我开始进行实验时,我注意到该公式的误差约为21亿。 我以为它可能已连接到我的变量,所以我尝试了DOUBLE,但仍然收到错误。
这是函数:
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函数始终将分子转换为LONG变量,即使先前已将其定义为Double或为硬编码数字!
测试自己:
MsgBox (2147483647) mod 3 'Maximum Long Value
VS.
MsgBox (2147483647 + 1) mod 3'Oh False!
我使用INT函数来复制mod计算Numerator -(INT(Numerator /Denominator)*Denominator)
但是还有很多其他可以避免的创造性方法。 甚至使用excel MOD函数进行Evaluate
可以正常工作。
底线: 我永远不会使用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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.