Results 1 to 22 of 22

Thread: Working with BIG numbers or LOTS of decimal places

Threaded View

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    May 2005
    Posts
    528

    Working with BIG numbers or LOTS of decimal places

    This code contains quite a few mathematical functions and is capable of handling very large numbers or numbers with lots of decimal places. the limit to how big a number they can handle is not 1.79769313486232E+308 which is the normal double limit, but 1.79769313486232E+308 DIGITS LONG!
    functions included are: add, subtract, divide, multiply, square root, mod and power.
    they work by using long division, long addition etc
    they cannot handle negative numbers and the power function ( y^x ) only supports x being a whole number up to the size of double precision, but y can have decimals and be very large like the rest.
    it also needs some work as i know they can be alot faster, any suggestions to make them faster will be greatly appreciated.
    here they are, this must be put in a module:
    UPDATES:
    indented
    improved code with si's suggestions
    attatched a sample project which uses this module to calculate pi (end of second post)
    improved again
    Code:
    'Long math functions by karl baker
    'you are free to use these in your own projects as long as credit is given
    
    Public Function divide(tnum1 As String, tnum2 As String, tplaces As String) As String
    
    Dim result As String
    Dim times As Long
    Dim val3 As String
    Dim loopcount As Long
    Dim last As Boolean
    Dim num1 As String
    Dim num2 As String
    Dim places As String
    places = tplaces
    num1 = tnum1
    num2 = tnum2
    last = False
    'start the loop
    
    Do
        'loopcount keeps track of how many dp we have calculated
        loopcount = loopcount + 1
        result = 0
        times = 0
        'see how many times num1 goes into num2
        Do Until morethan(result, num1)
            result = add(result, num2)
            times = times + 1
            
        Loop
        result = subtract(result, num2)
        times = times - 1
        'if num1 goes into num2 exactly then this is the last calculation we need to do
        If result = num1 Then last = True
        
        If loopcount <> places And last = False Then
            val3 = subtract(num1, result)
            'multiply num1 by 10 to use in the next loop round for calculating the next digit
            num1 = multiply(val3, 10)
        End If
        
        If loopcount = 1 And last = False Then
            divide = times & "."
        Else
            divide = divide & times
        End If
    DoEvents
    Loop Until loopcount = places Or last = True
        
        
        
     If InStr(divide, ".") > 0 Then
      Do While Right(divide, 1) = "0"
        divide = Left(divide, Len(divide) - 1)
      Loop
    End If
        
    
    
    
    End Function
    
    Public Function sqrt(tnum1 As String) As String
    Dim num1 As String
    num1 = tnum1
    Dim tempnum1 As String
    Dim lastnum As String
    Dim multiply1 As String
    tempnum1 = 2
    lastnum = 1
    
    Do
        'square tempnum
        multiply1 = multiply(tempnum1, tempnum1)
        'if tempnum^2 is bigger than num1 then we know we have found the square root
        If morethan(multiply1, num1) Then Exit Do
        lastnum = tempnum1
        'add the appropriate number to tempnum
        If morethan(subtract(num1, multiply1), 1000000000000#) Then
            tempnum1 = add(tempnum1, 1000000)
        ElseIf morethan(subtract(num1, multiply1), 10000000000#) Then
            tempnum1 = add(tempnum1, 100000)
        ElseIf morethan(subtract(num1, multiply1), 100000000) Then
            tempnum1 = add(tempnum1, 10000)
        ElseIf morethan(subtract(num1, multiply1), 1000000) Then
            tempnum1 = add(tempnum1, 1000)
        ElseIf morethan(subtract(num1, multiply1), 10000) Then
            tempnum1 = add(tempnum1, 100)
        ElseIf morethan(subtract(num1, multiply1), 100) Then
            tempnum1 = add(tempnum1, 10)
        ElseIf morethan(subtract(num1, multiply1), 50) Then
            tempnum1 = add(tempnum1, 5)
        ElseIf morethan(subtract(num1, multiply1), 10) Then
            tempnum1 = add(tempnum1, 3)
        Else
            tempnum1 = add(tempnum1, 1)
        End If
    DoEvents
    Loop
    sqrt = lastnum
    End Function
    
    Public Function Lmod(tnum1 As String, tnum2 As String) As String
    Dim result As String
    Dim num1 As String
    Dim num2 As String
    num1 = tnum1
    num2 = tnum2
    result = 0
    
    Do Until morethan(result, num1)
        result = add(result, num2)
    DoEvents
    Loop
    
    'subtract to get the remainder we're after
    Lmod = subtract(result, num1)
    If Lmod = tnum2 Then Lmod = 0
    
    
    End Function
    
    
    Public Function add(tnum1 As String, tnum2 As String) As String
    Dim num1 As String
    Dim num2 As String
    num1 = tnum1
    num2 = tnum2
    Dim i As Long
    Dim length As Long
    Dim temp As Byte
    Dim carry As Byte
    
    checkdec:
    'check whether the numbers contain a decimal place
    If InStr(num1, ".") > 0 And InStr(num2, ".") > 0 Then
        'if they do then format them so that the decimal place is in the same pasition for both of them
        If (Len(num1) - InStr(num1, ".")) < (Len(num2) - InStr(num2, ".")) Then
            Do
                num1 = num1 & "0"
            Loop Until (Len(num1) - InStr(num1, ".")) = (Len(num2) - InStr(num2, "."))
        ElseIf (Len(num1) - InStr(num1, ".")) > (Len(num2) - InStr(num2, ".")) Then
            Do
                num2 = num2 & "0"
            Loop Until (Len(num1) - InStr(num1, ".")) = (Len(num2) - InStr(num2, "."))
        End If
        
    ElseIf InStr(num1, ".") > 0 And InStr(num2, ".") = 0 Then
        num2 = num2 & "."
        GoTo checkdec
    ElseIf InStr(num1, ".") = 0 And InStr(num2, ".") > 0 Then
        num1 = num1 & "."
        GoTo checkdec
    End If
    
    If Len(num1) > Len(num2) Then
        length = Len(num1)
        num2 = String$(length - Len(num2), "0") & num2
    
    ElseIf Len(num2) > Len(num1) Then
        length = Len(num2)
        num1 = String$(length - Len(num1), "0") & num1
    Else
        length = Len(num1)
    End If
    
    carry = 0
    'start adding the numbers together
    For i = 1 To length
        If Mid(num1, (length - i + 1), 1) = "." Then
            add = "." & add
        Else
            temp = Val(Mid(num1, (length - i + 1), 1)) + Val(Mid(num2, (length - i + 1), 1)) + carry
            If temp < 10 Then
                add = temp & add
                carry = 0
            Else
                add = Right(temp, 1) & add
                carry = Left(temp, 1)
            End If
        End If
    
    Next i
    
    If carry > 0 Then add = carry & add
    
    
        Do While Left(add, 1) = "0"
       add = Right(add, Len(add) - 1)
        Loop
    
    If Left(add, 1) = "." Then add = "0" & add
    
    
    
    End Function
    
    Public Function morethan(tnum1 As String, tnum2 As String) As Boolean
    Dim i As Long
    Dim length As Long
    Dim temp As Byte
    Dim carry As Byte
    Dim num1 As String
    Dim num2 As String
    num1 = tnum1
    num2 = tnum2
    
    checkdec:
    'format just like in add
    If InStr(num1, ".") > 0 And InStr(num2, ".") > 0 Then
        If (Len(num1) - InStr(num1, ".")) < (Len(num2) - InStr(num2, ".")) Then
            Do
                num1 = num1 & "0"
            Loop Until (Len(num1) - InStr(num1, ".")) = (Len(num2) - InStr(num2, "."))
        ElseIf (Len(num1) - InStr(num1, ".")) > (Len(num2) - InStr(num2, ".")) Then
            Do
                num2 = num2 & "0"
            Loop Until (Len(num1) - InStr(num1, ".")) = (Len(num2) - InStr(num2, "."))
        End If
    ElseIf InStr(num1, ".") > 0 And InStr(num2, ".") = 0 Then
        num2 = num2 & "."
        GoTo checkdec
    ElseIf InStr(num1, ".") = 0 And InStr(num2, ".") > 0 Then
        num1 = num1 & "."
        GoTo checkdec
    End If
    
    If Len(num1) > Len(num2) Then
        length = Len(num1)
        num2 = String$(length - Len(num2), "0") & num2
    
    ElseIf Len(num2) > Len(num1) Then
        length = Len(num2)
        num1 = String$(length - Len(num1), "0") & num1
    Else
        length = Len(num1)
    End If
    
    morethan = False
    
    'check if it is more than the other
    For i = 1 To length
        If Mid(num1, i, 1) <> "." Then
        Select Case Val(Mid(num1, i, 1))
            Case Is > Val(Mid(num2, i, 1))
                morethan = True
                Exit Function
            Case Is < Val(Mid(num2, i, 1))
                morethan = False
                Exit Function
            End Select
        End If
    
    Next i
    
    End Function
    continued in next post
    Last edited by killo; Feb 27th, 2008 at 11:30 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width