1

I have recently created a macro that uses a lot of large (like over 100 digits in decimal) numbers. To handle them, I scraped around the internet for ideas and optimized a lot of the stuff I found to meet my requirements.

However, I found a large number multiplication function that works... but seems to me as not to be too efficient.

I tried to think up my own algo from scratch, and I tried to optimize this one... but I can't seem to get it any faster.

I was trying to think of a method that wouldn't require factorOneNbr to reference LargeMult... but got nothing.

If anyone has any pointers I would appreciate it.

Thanks!

Here's the code:

Public Sub Initialize()
Static Initialized As Boolean
If Initialized Then Exit Sub
Initialized = True
cDecMax = _
    CDec(Replace("79,228,162,514,264,337,593,543,950,335", ",", ""))
        'this is 2^96-1
cDecMaxLen = Len(cDecMax) - 1
cSqrDecMaxLen = cDecMaxLen \ 2
End Sub

Function Ceil(x As Single) As Long
    If x < 0 Then Ceil = Fix(x) Else Ceil = -Int(-x)
End Function

Function LargeMult(ByVal Nbr1 As String, ByVal Nbr2 As String) As String
    Initialize
    Dim negative As Boolean
    negative = False

    If Left(Nbr1, 1) = "-" And Left(Nbr2, 1) = "-" Then
        Nbr1 = Right(Nbr1, Len(Nbr1) - 1)
        Nbr2 = Right(Nbr2, Len(Nbr2) - 1)
    ElseIf Left(Nbr1, 1) = "-" Then
        Nbr1 = Right(Nbr1, Len(Nbr1) - 1)
        negative = True
    ElseIf Left(Nbr2, 1) = "-" Then
        Nbr2 = Right(Nbr2, Len(Nbr2) - 1)
        negative = True
    End If

    If Len(Nbr1) <= cSqrDecMaxLen And Len(Nbr2) <= cSqrDecMaxLen Then
        LargeMult = CStr(CDec(Nbr1) * CDec(Nbr2))
        If negative Then LargeMult = "-" & LargeMult
        Exit Function
    End If
    If Len(Nbr1) > cSqrDecMaxLen Then
        LargeMult = factorOneNbr(Nbr1, Nbr2)
    Else
        LargeMult = factorOneNbr(Nbr2, Nbr1)
    End If

    If negative Then LargeMult = "-" & LargeMult

End Function

Private Function factorOneNbr(ByVal LargeNbr As String, _
        ByVal Nbr2 As String) As String
    Dim NbrChunks As Integer, i As Integer, _
        Nbr1Part As String, PowersOf10 As Integer, _
        Rslt As String, FinalRslt As String
    FinalRslt = "0"
    NbrChunks = Ceil(Len(LargeNbr) / cSqrDecMaxLen) - 1
    For i = NbrChunks To 0 Step -1
        Nbr1Part = Mid(LargeNbr, i * cSqrDecMaxLen + 1, cSqrDecMaxLen)
        Rslt = LargeMult(Nbr1Part, Nbr2)
        FinalRslt = LargeAdd(FinalRslt, Rslt & String(PowersOf10, "0"))
        PowersOf10 = PowersOf10 + Len(Nbr1Part)
        Next i
    factorOneNbr = FinalRslt
End Function
Community
  • 1
  • 1
user3074620
  • 3,637
  • 1
  • 14
  • 19
  • Have you tried http://en.wikipedia.org/wiki/Schönhage–Strassen_algorithm ? – zdk Aug 23 '14 at 16:12
  • 3
    I think this would be a good question for [Code Review](https://codereview.stackexchange.com/), *if* you include the `LargeAdd` function and it works as intended. As it is, this doesn't compile and I can't verify that it works. – RubberDuck Aug 23 '14 at 22:31
  • Some pointers available here on Stack Overflow I have found using Google follow: http://stackoverflow.com/questions/1218149/arbitrary-precision-arithmetic-explanation and http://stackoverflow.com/questions/5318068/very-large-numbers-in-java-without-using-java-math-biginteger, to find them I used Google queries "_site:stackoverflow.com large number arithmetics_" and "_java large number arithmetics_". With those queries you can surely find more pointers – xmojmr Aug 25 '14 at 19:10
  • As ckuhn203 said, your code is incomplete. Post a working example and we can be far more helpful. – AndASM Sep 10 '14 at 18:32

0 Answers0