すっごく長い整数

任意の長さの自然数での算術演算用の小さなライブラリを打ち切りました。 Visual Basic for Applications(VBA)で作成され、Excelに組み込まれているため、+-* /操作をオーバーライドすることはできず、フォームの2つの引数で関数を呼び出すことですべてが解決されます



文字列としてのLongADD(文字列としてのs1、文字列としてのs2)



ただし、Excelシートのセルから関数(またはその組み合わせ)を直接呼び出すことができます。すべてが明確で理解しやすいものです。 そして、はい、自然数は文字列として渡されます。 VBAの最大文字列長は約2 31 = 2 147 483 648(私のLongPower関数(「2」、31)で計算)なので、さまざまなもので遊ぶのに十分です。



たとえば、Rivest、Shamir、およびAldemanによる画期的な記事からの2つの素数の乗算(最新の暗号化はすべてコード内にあります(コードでは、これらは定数RSA1、RSA2です))







カット-VBAコードの下で、マクロサポート(* .xlsmなど)を使用してExcelファイルのモジュールに単純に挿入できます。



PSは、素因数への分解の競合にコードを使用しようとはしません。 彼は20億桁の数字を理解していますが、そのようなタスクにはめちゃめちゃ遅いです。

あなたがまだ成功すればPPS、利益の10%-私に

PPPSいいえ、15%以上





' 2 ,

Public Const RSA1 = "3490529510847650949147849619903898133417764638493387843990820577"

Public Const RSA2 = "32769132993266709549961988190834461413177642967992942539798288533"



'

Public Function LongAdd(s1 As String, s2 As String) As String



'

Dim Carry As Byte, Digit1 As Byte, Digit2 As Byte

Dim Result As String



Carry = 0

Result = ""



'

If Len(s1) > Len(s2) Then

s2 = String(Len(s1) - Len(s2), "0") & s2

Else

s1 = String(Len(s2) - Len(s1), "0") & s1

End If



'

For i = Len(s1) To 1 Step -1

Digit1 = CByte(Mid(s1, i, 1))

Digit2 = CByte(Mid(s2, i, 1))



Result = ((Carry + Digit1 + Digit2) Mod 10) & Result

Carry = (Carry + Digit1 + Digit2) \ 10

Next



If Carry > 0 Then Result = Carry & Result



LongAdd = Result



End Function



'

Public Function LongMultiply(ByVal s1 As String, ByVal s2 As String) As String



Dim Result As String, s As String

Result = "0"



' ,

If Len(s1) < Len(s2) Then

s = s1

s1 = s2

s2 = s

End If



'

s2 = String(Len(s1) - Len(s2), "0") & s2



'

For i = Len(s2) To 1 Step -1

Result = LongAdd(Result, LongMultiplyDigit(s1, Mid(s2, i, 1)) & String(Len(s2) - i, "0"))

Next



LongMultiply = Result



End Function



'

Public Function LongMultiplyDigit(s1 As String, s2 As String) As String



'

Dim Carry As Byte, Digit1 As Byte, Digit2 As Byte

Dim Result As String



Carry = 0

Result = ""

Digit2 = CByte(Left(s2, 1))



If Digit2 = 0 Then

LongMultiplyDigit = "0"

Exit Function

End If



For i = Len(s1) To 1 Step -1

Digit1 = CByte(Mid(s1, i, 1))



Result = ((Carry + Digit1 * Digit2) Mod 10) & Result

Carry = (Carry + Digit1 * Digit2) \ 10

Next



If Carry > 0 Then Result = Carry & Result

LongMultiplyDigit = Result



End Function



'

Public Function LongSubstract(ByVal s1 As String, ByVal s2 As String) As String



'

Dim Carry As Byte, Digit1 As Byte, Digit2 As Byte

Dim Result As String



Carry = 0

Result = ""



If LongCompare(s1, s2) Then

For i = Len(s1) To 1 Step -1



Digit1 = CByte(Mid(s1, i, 1))



If i - (Len(s1) - Len(s2)) < 1 Then

Digit2 = 0

Else

Digit2 = Mid(s2, i - (Len(s1) - Len(s2)), 1)

End If



If Digit1 >= Digit2 + Carry Then

Result = CStr(Digit1 - Carry - Digit2) & Result

Carry = 0

Else

Result = CStr(10 + Digit1 - Carry - Digit2) & Result

Carry = 1

End If

Next



LongSubstract = LongTrim(Result)

Else

LongSubstract = "0"

End If



End Function



'

Public Function LongDivide(ByVal s1 As String, ByVal s2 As String) As String



' ,

Dim Dividend As String, Residue As String, Quotient As String, Digit As Byte



' ,

If Not LongCompare(s1, s2) Then

LongDivide = "0"

Exit Function

End If



Dividend = ""

Residue = s1

Quotient = ""



While Len(Residue) > 0



Dividend = LongTrim(Dividend & Left(Residue, 1))

Residue = Right(Residue, Len(Residue) - 1)



If LongCompare(Dividend, s2) Then

For Digit = 1 To 9

If Not LongCompare(Dividend, LongMultiplyDigit(s2, CStr(Digit))) Then Exit For

Next



Quotient = Quotient & CStr(Digit - 1)

Dividend = LongSubstract(Dividend, LongMultiplyDigit(s2, CStr(Digit - 1)))

Else

Quotient = Quotient & "0"

End If



Wend



LongDivide = LongTrim(Quotient)



End Function



' . 0! = 1

Public Function LongFactor(N As Long) As String



Dim Fact As String, i As Long



Fact = "1"

For i = 2 To N

Fact = LongMultiply(Fact, CStr(i))

Next

LongFactor = Fact



End Function



' .

' (), -

Public Function LongPower(s As String, p As Long) As String



Dim Power As String



Power = s



For i = 2 To p

Power = LongMultiply(Power, s)

Next



LongPower = Power



End Function



' -

' TRUE

Public Function LongCompare(s1 As String, s2 As String) As Boolean



If Len(s1) <> Len(s2) Then

LongCompare = (Len(s1) > Len(s2))

Else

For i = 1 To Len(s1)

If CByte(Mid(s1, i, 1)) <> CByte(Mid(s2, i, 1)) Then

LongCompare = CByte(Mid(s1, i, 1)) >= CByte(Mid(s2, i, 1))

Exit Function

Else

LongCompare = True

End If

Next

End If



End Function



' -

Function LongTrim(s As String) As String



Dim TrimString As String

TrimString = s



While (Left(TrimString, 1) = "0") And (Len(TrimString) > 1)

TrimString = Right(TrimString, Len(TrimString) - 1)

Wend



LongTrim = TrimString



End Function



'

Public Function GroupDigits(s As String) As String



Dim d As String

d = ""



While Len(s) > 0

d = " " & Right(s, 3) & d

s = Left(s, Len(s) - 3)



Wend



GroupDigits = d



End Function








All Articles