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