# Large Number Operations

In the past there have been many inquiries about how to perform math functions on numbers that are greatly larger that the standard variables which come embedded in Visual Basic, such as the Long. What do you do when you want to work with numbers that have a total length of digits that reach into the billions? You sure can't store those in a conventional variable, or perform normal operations on them.

The Solution is the Long Math module. In this module there are 4 functions: `IntAddition`, `IntSubtraction`, `IntMultiply` and `IntDivide`. Each takes two strings, and each performs the the operation in the title on the strings, which are suppose to contain these massively large integers.

This is version 1 of this code. I am currently working on a second version that will take and handle positive and negative numbers, be more fault tolerent, and work with decimals. The attached source code download also includes a demonstration project.

```'****************************************************************** ' Extra Long Integer Mathematics ' ' Programmer: Eric L. Truitte ' Contact Info: [email protected] ' Date Created: April 3, 2003 ' Purpose: '          Functions to handle mathmatics too large for '          conventional variables and operations. ' ' Copyright notice: '          This code is subject to the GNU General Public License. '          If you make changes, add a Revision note. '          This code is Open Source and should remain so. ' '****************************************************************** ' Revision Date: April 5, 2003 ' Programmer: Eric L. Truitte ' Details: '          Addition and Multiplication tested and finallized '          Update comments ' ' Revision Date: February 19, 2005 ' Programmer: Eric L. Truitte ' Details: '          Finallized Subtraction and Division '          Updated comments ' '****************************************************************** 'Notes: ' 'THERE IS CURRENTLY VERY LITTLE FAULT TOLERANCE IN THE FUNCTIONS 'entering a non-numeric character will cause errors.  If you intend to use these, 'make sure what you pass in is just a string of integers. ' 'To do list: '  Decimals '  Negatives '  Multi-string length numbers ' 'What is the largest number that can be handled at this point? '          A String can hold roughly the largest size of a Long value in characters. '          That is the number of potential digits you can have in a number. ' 'I will be working on a decimal handling, possitive/negative, and arrays of strings 'containing segments of an Extra Long Integer.  I hope if you have need of such 'capacity of numbers that you have a system that can adequitely handle both 'system overhead and processor side-effects from overclocking for an extended 'period of time. ' '****************************************************************** Public STOPNOW As Boolean 'This is a sentinel variable used in the demo form Public Function IntAddition(ByVal FirstNum As String, ByVal SecondNum As String) As String Dim a As Long, DifLen As Long, TempStr As String, TempNum As Integer Dim Num1 As String, Num2 As String, TempNum1 As Integer, TempNum2 As Integer Dim CarryOver As Integer, LeftOvers As Long 'Setup the numbers so that they are easier to handle. 'I originally had about 10 nested if statements that this block 'of code simplifies Dramatically.   If Len(FirstNum) >= Len(SecondNum) Then       Num1 = FirstNum       Num2 = SecondNum   Else       Num2 = FirstNum       Num1 = SecondNum   End If   'Just setup some of the variables that need an initial value   DifLen = Len(Num1) - Len(Num2)   CarryOver = 0   LeftOvers = DifLen   'Ok, now for the real math.  Looping from the end of the numbers 'just like our preschool teachers taught us, we add numbers that 'line up in the 'places' (I.E. ones, tens, hundreds, thousands, etc)   For a = Len(Num2) To 1 Step -1       TempNum1 = Int(Mid(Num1, a + DifLen, 1))       TempNum2 = Int(Mid(Num2, a, 1))       TempNum = TempNum1 + TempNum2 + CarryOver       CarryOver = TempNum \ 10       TempStr = (TempNum - (CarryOver * 10)) & TempStr       DoEvents       If STOPNOW = True Then GoTo StopAdd   Next a   'What do we do if there is a 1 or a 2 that carries over outside the 'numbers that line up in the places, well, we do the following block of 'code.  The do loop is used incase we get a situation like this: ' '    199999  When you add 1 to a set of nines it continues to '    _+___1  Carry over until it hits the first digit '    200000   Do Until CarryOver = 0 Or LeftOvers = 0       TempNum = Int(Mid(Num1, LeftOvers, 1)) + CarryOver       CarryOver = TempNum \ 10       TempStr = (TempNum - (CarryOver * 10)) & TempStr       LeftOvers = LeftOvers - 1   Loop   'Since there are two possible ways of exiting the Loop above, we need 'to test and apply the other variable and its associated values in the following 'two if statements. 'Handle a possible carryover that will drop off the front end creating a new place.   If CarryOver > 0 Then TempStr = CarryOver & TempStr 'add any of the numbers that are remaining on the left side of the longer string   If LeftOvers > 0 Then TempStr = Left(Num1, LeftOvers) & TempStr 'and return the value StopAdd:   IntAddition = TrimZeros(TempStr) End Function Public Function IntMultiply(ByVal FirstNum As String, ByVal SecondNum As String) As String Dim ZeroStr As String Dim a As Long, b As Long, Multiplier1 As Integer, Multiplier2 As Integer Dim Num As Integer, CarryOver As Integer, TempStr As String, TallyStr As String 'THIS FUNCTION IS COMPLETE AND WORKS 'This function can handle two extra longs. It cycles through 'the firstnum one digit at a time from secondnum. 'this function works on the distrubution Principle of Multiplication: ' 9999 * 222 = (9999 * 2) + (9999 * 20) + (9999 * 200) ' 'The zero's are concatinated on after the multiplication takes place. ' 'This function is dependent on the IntAddition function above.   For a = Len(FirstNum) To 1 Step -1       'setup variables for this loop of multiplication       TempStr = ""       CarryOver = 0       Multiplier1 = Mid(FirstNum, a, 1)             'Multiply one digit at a time from right to left       For b = Len(SecondNum) To 1 Step -1         Multiplier2 = Mid(SecondNum, b, 1)                 Num = (Multiplier1 * Multiplier2) + CarryOver         CarryOver = Num \ 10         TempStr = (Num - (CarryOver * 10)) & TempStr       Next b               'Check to see if the multiplication added a new digit       If CarryOver > 0 Then TempStr = CarryOver & TempStr             'Add the zeros       TempStr = TempStr & ZeroStr       TallyStr = IntAddition(TempStr, TallyStr)       ZeroStr = ZeroStr & "0"             DoEvents             'sentinel       If STOPNOW = True Then GoTo StopMultiply   Next a   StopMultiply:   IntMultiply = TrimZeros(TallyStr) End Function Public Function TrimZeros(ByVal Num As String) As String Dim a As Long, TempStr As String   For a = 1 To Len(Num)       If Mid(Num, a, 1) <> 0 Then GoTo YuckFu   Next a   TrimZeros = "0" Exit Function YuckFu:   TrimZeros = Mid(Num, a, Len(Num) - a + 1) End Function Public Function IntSubtract(ByVal FirstNum As String, ByVal SecondNum As String) As String '*** 'DO NOT change the integers to bytes, there are negative values in this function '*** Dim Num1 As String, Num2 As String, a As Long, Neg As Boolean, DifLen As Long Dim TempStr As String, TempNum1 As Integer, TempNum2 As Integer Dim TempNum As Integer, Barrow As Byte 'This function operates on a theory known as Two-Compliment. 'If you want to know more, look for it at www.mathforum.com 'This function works great now 'This block of code arranges the numbers into the Num1 and Num2 based on 'which number is larger.  This prevents a great number of errors if the numbers 'dont line up, or if the larger number is taken from the smaller number.   If Len(FirstNum) > Len(SecondNum) Then       Num1 = FirstNum       Num2 = SecondNum       Neg = False   ElseIf Len(FirstNum) < Len(SecondNum) Then       Num1 = SecondNum       Num2 = FirstNum       Neg = True   Else   'In the case that the strings are of equal length we have this pretty little 'set of code to find which number has the first larger digit.       For a = 1 To Len(FirstNum)         If Int(Mid(FirstNum, a, 1)) > Int(Mid(SecondNum, a, 1)) Then             Num1 = FirstNum             Num2 = SecondNum             Neg = False             GoTo ContinSubtraction                     ElseIf Int(Mid(FirstNum, a, 1)) < Int(Mid(SecondNum, a, 1)) Then             Num1 = SecondNum             Num2 = FirstNum             Neg = True             GoTo ContinSubtraction         End If                 DoEvents                 'sentinel         If STOPNOW = True Then GoTo ExitFunction       Next a       'In the case that no larger digit is found, then guess what, its a perfect 'subtraction, so we don't need to do the function, just assign a 0 outside the end.       GoTo ExitFunction   End If   ContinSubtraction: 'If we have a difference in length then ajust with 0's that will not affect the calculations. 'This allows us to get all the digits into the final out number.   DifLen = Len(Num1) - Len(Num2)   Num2 = String(DifLen, "0") & Num2   Barrow = 0 'lets do some math   For a = Len(Num2) To 1 Step -1         'Pick out the individual digit from each number       TempNum1 = Int(Mid(Num1, a, 1)) - Barrow       TempNum2 = Int(Mid(Num2, a, 1))       Barrow = 0               'Perform single digit subraction using the Two Compliment theory       If TempNum1 >= TempNum2 Then         TempNum = TempNum1 - TempNum2               ElseIf TempNum1 < TempNum2 Then         TempNum = (TempNum1 + 10) - TempNum2         Barrow = 1       End If             'Assign new digit to the final string.       TempStr = CStr(TempNum) & TempStr             DoEvents             'sentinel       If STOPNOW = True Then GoTo ExitFunction   Next a 'now, since we are subtracting, we need to determine if the number being returned is a negative. 'Just to note, the Trim is to remove unneccsary zero's at the head(left) of the return number.   If Neg = True Then       IntSubtract = "-" & TrimZeros(Trim(TempStr))   Else       IntSubtract = TrimZeros(Trim(TempStr))   End If Exit Function ExitFunction:   IntSubtract = 0 End Function Public Function IntDivide(ByVal FirstNum As String, ByVal SecondNum As String) As String 'Before we even alocate memory for variables, test for some very important error values If Len(FirstNum) < Len(SecondNum) Or InStr(1, IntSubtract(FirstNum, SecondNum), "-") > 0 Then   MsgBox "Fault: Extra Long Division does not support dividing a shorter number by a longer number, as this requires decimals which are not currently handled."   ElseIf TrimZeros(SecondNum) = "" Then   MsgBox "Fault: Cannot divide by Zero."   ElseIf TrimZeros(SecondNum) = "" Then   GoTo EndFunc   Else   GoTo continDivide End If GoTo ExitDivide 'After passing the error checking, lets get started with some division continDivide: Dim Num1 As String, DivTotal As String, DivMult As String Dim DifLen As Long, DivSub As String, TempNum As String   'Initiallize values   Num1 = FirstNum   DivTotal = "0"   DifLen = (Len(Num1) - Len(SecondNum))   DivMult = String(DifLen, "0")   DivSub = SecondNum & DivMult     'Lets do some division   Do Until (Len(Num1) < Len(SecondNum) Or Num1 = "0" Or (InStr(1, IntSubtract(Num1, SecondNum), "-") > 0 And DivMult = "")) Or STOPNOW = True             'The way this division works is it subtracts values from the divided number       'until no more can be subtracted.  This sets up a the largest possible number       'that can be subtracted from the number so that you remove larger chucks of       'Numbers at a time and waste less CPU Cycles doing it.       If DifLen >= 0 Then DivMult = String(DifLen, "0")       DivSub = SecondNum & DivMult             If InStr(1, IntSubtract(Num1, DivSub), "-") > 0 Then         If DifLen > 0 Then             DivMult = String(DifLen - 1, "0")             DivSub = SecondNum & DivMult         Else             Exit Do         End If       End If             'Perform the accually math.  DivTotal adds up how many times the original       'number has been subtracted from the divided number. Num1 is the working       'number.       DivTotal = IntAddition(DivTotal, "1" & DivMult)       Num1 = IntSubtract(Num1, DivSub)       DifLen = Len(Num1) - Len(SecondNum)             DoEvents             'sentinel       If STOPNOW = True Then GoTo ExitDivide   Loop     'Since there are no decimals, we return return the devide results with a remainder.   IntDivide = DivTotal & "r" & Num1   EndFunc: Exit Function ExitDivide: IntDivide = "NaN" End Function```

## You might also like... Programming since I was 12 in the mid-90's, I've gotten a taste of professional programming and never looked back at other childhood aspirations. I love writing code. It's my career.

### Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

### Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“My definition of an expert in any field is a person who knows enough about what's really going on to be scared.”