2017-07-08 3 views
0

更新済み 解決後にこのポストをクリーンアップします。要約すると、次の最高の素数(=NextHighestPrimeNumber(100)101を返す)を計算したExcelのユーザー定義の式を作成していました。私が実験を始めたとき、私はこの数式が約21億の誤差になることに気付きました。私はそれが私の変数に接続されていると思ったので、私はDOUBLEを試しましたが、まだエラーがありました。それは以前にダブルのように定義またはハードコード化された番号である場合であっても、VBA MOD機能は常に LONG変数に分子を変換しているため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

* "9,223,372,036,854,775,807までの範囲を持つ必要がありますLONG変数" *: 'ZZコードを失敗したとのフラグが立てられたエラーを投げました。後者では、long型は4バイトです。 –

+1

"ロングは、-2,147,483,648から 2,147,483,647までの範囲の4バイト(32ビット)です。MSDNでこの定義はどこで見つかりましたか? [チップピアソン](https://www.pcreview.co.uk/threads/vba-long-data-type-overflow.959041/) – pnuts

+2

明らかに、VB.NETの参考資料を参考にしています。代わりに[VBAリファレンス](https://msdn.microsoft.com/en-us/library/aa263420(VS.60).aspx)を参照してください。 – GSerg

答えて

1

問題は次のとおりです。ここで

は機能です!

テスト自分自身:

MsgBox (2147483647) mod 3 'Maximum Long Value

対。

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

私はモッズ計算を複製するためにINT関数を使用Numerator -(INT(Numerator /Denominator)*Denominator)が、回避するために、他の創造的な方法がたくさんあります。 excel MOD機能を持つEvaluateさえ正しく動作しました。

Bottomline:私は潜在的に、私は私の最初のポストので、大幅に私のコードをクリーンアップしていることをコメントアウト悪い行を残してきた2億

を超えることができたすべての計算にMODを使用するつもりはありませんよそれは** VB.net **ない** 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: 

    '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」 - [データ型の概要 - MSDN VBA](https://msdn.microsoft.com/en-us)を表示します。/vba/language-reference-vba/articles/data-type-summary) –

関連する問題