Attribute VB_Name = "BigNumbers"
Option Explicit

Public Const MaxLength = 120 ' longest number/2
Dim Pom0(MaxLength) As Long
Dim LengthPom0 As Long
Dim Pom1(MaxLength) As Long
Dim LengthPom1 As Long
Dim Pom2(MaxLength) As Long
Dim LengthPom2 As Long
Dim Pom3(MaxLength) As Long
Dim LengthPom3 As Long
Dim Pom4(MaxLength) As Long
Dim LengthPom4 As Long
Dim Pom5(MaxLength) As Long
Dim LengthPom5 As Long
Dim Pom6(MaxLength) As Long
Dim LengthPom6 As Long
Dim Pom7(MaxLength) As Long
Dim LengthPom7 As Long
Dim K1(MaxLength) As Long
Dim K10(MaxLength) As Long
Dim K100(MaxLength) As Long
Dim K200(MaxLength) As Long
Dim K10000(MaxLength) As Long

Public Function CompareB(a() As Long, LengthA As Long, b() As Long, LengthB As Long) As Long
Dim i As Long
Select Case LengthA - LengthB
Case Is < 0
    CompareB = -1
Case Is = 0
    CompareB = 0
    For i = 1 To LengthA
        Select Case a(LengthA - i + 1) - b(LengthA - i + 1)
        Case Is < 0
            CompareB = -1
            Exit For
        Case Is = 0
        Case Is > 0
            CompareB = 1
            Exit For
        End Select
    Next i
Case Is > 0
    CompareB = 1
End Select

End Function

Public Function BigNumberToText(c() As Long, Length As Long) As String
Dim i As Long
Dim pom As String
If c(0) = -1 Then
    pom = "-"
Else
    pom = ""
End If
pom = pom & Format$(c(Length), "0")
For i = Length - 1 To 1 Step -1
    pom = pom & Format$(c(i), "0000")
Next i
BigNumberToText = pom
End Function

Public Sub TextToBigNumber1(Tekst As String, a() As Long, LengthA As Long)
Dim i As Long
Dim Prvi As String
Dim MaxLengthPrvi As Long
Dim ostatak As Long
Prvi = Trim$(Tekst)
    a(0) = 0
     MaxLengthPrvi = Len(Prvi)
    If (MaxLengthPrvi \ 4) * 4 = MaxLengthPrvi Then
        LengthA = MaxLengthPrvi \ 4
        For i = 1 To LengthA
            a(i) = Mid$(Prvi, MaxLengthPrvi - i * 4 + 1, 4)
        Next i
    Else
        LengthA = MaxLengthPrvi \ 4 + 1
        ostatak = MaxLengthPrvi Mod 4
        For i = 1 To LengthA - 1
            a(i) = Mid$(Prvi, MaxLengthPrvi - i * 4 + 1, 4)
        Next i
        a(LengthA) = Mid$(Prvi, 1, ostatak)
    End If
End Sub



Public Sub TextToBigNumber(Tekst As String, a() As Long, LengthA As Long)
Dim i As Long
Dim Prvi As String
Dim MaxLengthPrvi As Long
Dim ostatak As Long
Prvi = Trim$(Tekst)
    a(0) = 0
     MaxLengthPrvi = Len(Prvi)
    If (MaxLengthPrvi \ 4) * 4 = MaxLengthPrvi Then
        LengthA = MaxLengthPrvi \ 4
        For i = 1 To LengthA
            a(i) = Mid$(Prvi, MaxLengthPrvi - i * 4 + 1, 4)
        Next i
    Else
        LengthA = MaxLengthPrvi \ 4 + 1
        ostatak = MaxLengthPrvi Mod 4
        For i = 1 To LengthA - 1
            a(i) = Mid$(Prvi, MaxLengthPrvi - i * 4 + 1, 4)
        Next i
        a(LengthA) = Mid$(Prvi, 1, ostatak)
    End If
End Sub





Public Sub MinusB(a() As Long, LengthA As Long, b() As Long, LengthB As Long, c() As Long, LengthC As Long)
Select Case CompareB(a, LengthA, b, LengthB)
Case Is < 0
    Call MinusBV(b, LengthB, a, LengthA, c, LengthC)
    c(0) = -1
Case Is = 0
    c(1) = 0
    LengthC = 1
    c(0) = 0
Case Is > 0
    Call MinusBV(a, LengthA, b, LengthB, c, LengthC)
    c(0) = 0
End Select
End Sub

Public Function IsItBigNumber(Ulaz As String) As Boolean
Dim pom As String
Dim Pom1 As String
Dim i As Long
Dim IsItBigNumber1 As Boolean
Pom1 = Ulaz
'pom = Left$(Pom1, 300)
'    For i = 1 To Len(Pom1) \ 300
  ' pom = Mid$(Pom1, 300 * i, 300)
   pom = Right$(Pom1, 300)
 
 '   Next i
IsItBigNumber = True
End Function

Public Sub AddBSigned(a() As Long, LengthA As Long, b() As Long, LengthB As Long, c() As Long, LengthC As Long)
If a(0) = 0 And b(0) = 0 Then
    Call AddB(a, LengthA, b, LengthB, c, LengthC)
End If
If a(0) < 0 And b(0) < 0 Then
    Call AddB(a, LengthA, b, LengthB, c, LengthC)
    c(0) = -1
End If
If a(0) = 0 And b(0) < 0 Then
    Call MinusB(a, LengthA, b, LengthB, c, LengthC)
End If
If a(0) < 0 And b(0) = 0 Then
    Call MinusB(b, LengthB, a, LengthA, c, LengthC)
End If

End Sub

Public Sub MinusBSigned(a() As Long, LengthA As Long, b() As Long, LengthB As Long, c() As Long, LengthC As Long)
If a(0) = 0 And b(0) = 0 Then
    Call MinusB(a, LengthA, b, LengthB, c, LengthC)
End If
If a(0) < 0 And b(0) < 0 Then
    Call MinusB(b, LengthB, a, LengthA, c, LengthC)
End If
If a(0) = 0 And b(0) < 0 Then
    Call AddB(a, LengthA, b, LengthB, c, LengthC)
    c(0) = 0
    
End If
If a(0) < 0 And b(0) = 0 Then
    Call AddB(b, LengthB, a, LengthA, c, LengthC)
    c(0) = -1
End If

End Sub

Public Sub MultBSigned(a() As Long, LengthA As Long, b() As Long, LengthB As Long, c() As Long, LengthC As Long)
Call MultB(a, LengthA, b, LengthB, c, LengthC)
If (a(0) = 0 And b(0) = 0) Or (a(0) < 0 And b(0) < 0) Then
    c(0) = 0
Else
    If LengthC = 1 And c(1) = 0 Then
        c(0) = 0
    Else
        c(0) = -1
    End If
End If
End Sub

Public Sub CopyB(a() As Long, LengthA As Long, b() As Long, LengthB As Long)
Dim i As Long
LengthB = LengthA
For i = 0 To LengthA
    b(i) = a(i)
Next i
End Sub


Public Sub DivBSigned(a() As Long, LengthA As Long, b() As Long, LengthB As Long, c() As Long, LengthC As Long, d() As Long, LengthD As Long)
Call DivB(a, LengthA, b, LengthB, c, LengthC, d, LengthD)
If (a(0) = 0 And b(0) = 0) Or (a(0) < 0 And b(0) < 0) Then
    c(0) = 0
Else
    If LengthC = 1 And c(1) = 0 Then
        c(0) = 0
    Else
        c(0) = -1
    End If
End If

End Sub

Public Sub DivB(a() As Long, LengthA As Long, b() As Long, LengthB As Long, c() As Long, LengthC As Long, d() As Long, LengthD As Long)
If LengthB = 1 And b(1) = 0 Then
    c(1) = 0
    LengthC = 1
    c(0) = 0
    Exit Sub
End If
If LengthB = 1 And b(1) = 1 Then
    Call CopyB(a, LengthA, c, LengthC)
    Exit Sub
End If
If LengthA = 1 And a(1) = 0 Then
    c(1) = 0
    LengthC = 1
    c(0) = 0
    Exit Sub
End If
Select Case CompareB(a, LengthA, b, LengthB)
Case Is < 0
    c(1) = 0
    LengthC = 1
    c(0) = 0
Case Is = 0
    c(1) = 1
    LengthC = 1
    c(0) = 0
Case Is > 0
    Call DivBInt(a, LengthA, b, LengthB, c, LengthC, d, LengthD)
End Select

End Sub

Public Sub DivBInt(a() As Long, LengthA As Long, b() As Long, LengthB As Long, c() As Long, LengthC As Long, d() As Long, LengthD As Long)
Dim i As Long
Dim j As Long
Dim StrA As String
Dim StrB As String
Dim StrC As String
Dim MaxLengthStrA As Long
Dim MaxLengthStrB As Long
Dim tr As String
K10(1) = 10
StrA = BigNumberToText(a, LengthA)
StrB = BigNumberToText(b, LengthB)
MaxLengthStrA = Len(StrA)
MaxLengthStrB = Len(StrB)
j = 0
Call TextToBigNumber(Left$(StrA, MaxLengthStrB), Pom2, LengthPom2)
Do While CompareB(Pom2, LengthPom2, b, LengthB) >= 0
    j = j + 1
    Call MinusBV(Pom2, LengthPom2, b, LengthB, Pom3, LengthPom3)
    Call CopyB(Pom3, LengthPom3, Pom2, LengthPom2)
Loop
StrC = Format$(j, "0")

For i = 1 To MaxLengthStrA - MaxLengthStrB
    j = 0
    Call MultB(Pom2, LengthPom2, K10, 1, Pom1, LengthPom1)
    Call TextToBigNumber(Mid$(StrA, MaxLengthStrB + i, 1), Pom2, LengthPom2)
    tr = BigNumberToText(Pom1, LengthPom1)
    tr = BigNumberToText(Pom2, LengthPom2)
    
    Call AddB(Pom1, LengthPom1, Pom2, LengthPom2, Pom3, LengthPom3)
    Call CopyB(Pom3, LengthPom3, Pom2, LengthPom2)
    Do While CompareB(Pom2, LengthPom2, b, LengthB) >= 0
        j = j + 1
        Call MinusBV(Pom2, LengthPom2, b, LengthB, Pom3, LengthPom3)
        Call CopyB(Pom3, LengthPom3, Pom2, LengthPom2)
    Loop
    StrC = StrC & Format$(j, "0")
Next i
Call CopyB(Pom2, LengthPom2, d, LengthD)
Call TextToBigNumber(StrC, c, LengthC)


End Sub

Public Sub AddB(a() As Long, LengthA As Long, b() As Long, LengthB As Long, c() As Long, LengthC As Long)
Dim prenos As Long
Dim i As Long
Dim j As Long
prenos = 0
If LengthA > LengthB Then
    LengthC = LengthA + 1
    For i = 1 To LengthB
        c(i) = a(i) + b(i) + prenos
        prenos = c(i) \ 10000
        c(i) = c(i) Mod 10000
    Next i
    i = LengthB + 1
    Do While prenos > 0 And i <= LengthA
        c(i) = a(i) + prenos
        prenos = c(i) \ 10000
        c(i) = c(i) Mod 10000
        i = i + 1
    Loop
    If i > LengthA Then
        c(i) = prenos
    Else
        For j = i To LengthA
            c(j) = a(j)
        Next j
        c(LengthA + 1) = 0
    End If
Else
    LengthC = LengthB + 1
    For i = 1 To LengthA
        c(i) = a(i) + b(i) + prenos
        prenos = c(i) \ 10000
        c(i) = c(i) Mod 10000
    Next i
    i = LengthA + 1
    Do While prenos > 0 And i <= LengthB
        c(i) = b(i) + prenos
        prenos = c(i) \ 10000
        c(i) = c(i) Mod 10000
        i = i + 1
    Loop
    If i > LengthB Then
        c(i) = prenos
    Else
        For j = i To LengthB
            c(j) = b(j)
        Next j
        c(LengthB + 1) = 0
    End If
End If
If c(LengthC) = 0 Then LengthC = LengthC - 1

End Sub

Public Sub MinusBV(a() As Long, LengthA As Long, b() As Long, LengthB As Long, c() As Long, LengthC As Long)
Dim prenos As Long
Dim i As Long
Dim j As Long
prenos = 0
LengthC = LengthA
For i = 1 To LengthB
    c(i) = a(i) - b(i) - prenos
    If c(i) < 0 Then
        c(i) = c(i) + 10000
        prenos = 1
    Else
        prenos = 0
    End If
Next i
i = LengthB + 1
Do While prenos > 0 And i <= LengthA
    c(i) = a(i) - prenos
    If c(i) < 0 Then
        c(i) = c(i) + 10000
        prenos = 1
    Else
        prenos = 0
    End If
    i = i + 1
Loop
If i > LengthA Then
    c(i) = prenos
Else
    For j = i To LengthA
        c(j) = a(j)
    Next j
End If
Do Until c(LengthC) <> 0 Or LengthC = 1
    LengthC = LengthC - 1
Loop

End Sub

Public Sub MultB(a() As Long, LengthA As Long, b() As Long, LengthB As Long, c() As Long, LengthC As Long)
Dim prenos As Long
Dim i As Long
Dim j As Long
If (LengthB = 1 And b(1) = 0) Or (LengthA = 1 And a(1) = 0) Then
    c(1) = 0
    LengthC = 1
    c(0) = 0
    Exit Sub
End If
If LengthB = 1 And b(1) = 1 Then
    Call CopyB(a, LengthA, c, LengthC)
    Exit Sub
End If
If LengthA = 1 And a(1) = 1 Then
    Call CopyB(b, LengthB, c, LengthC)
    Exit Sub
End If
prenos = 0
For i = 1 To LengthA + LengthB
    Pom0(i) = 0
Next i
For i = 1 To LengthB
    For j = 1 To LengthA
        Pom0(i + j - 1) = Pom0(i + j - 1) + a(j) * b(i)
        prenos = Pom0(i + j - 1) \ 10000
        Pom0(i + j - 1) = Pom0(i + j - 1) Mod 10000
        Pom0(i + j) = Pom0(i + j) + prenos
    Next j
Next i

LengthPom0 = LengthA + LengthB
Do Until Pom0(LengthPom0) <> 0 Or LengthPom0 = 1
    LengthPom0 = LengthPom0 - 1
Loop
Call CopyB(Pom0, LengthPom0, c, LengthC)
End Sub

