Sub test_AddDecimal()
Debug.Print AddDecimal("123.0000000000000000000000001", _
"123.9999999999999999999999999")
End Sub
Function AddDecimal$(Optional ByVal numA$ = "0", _
Optional ByVal numB$ = "0", _
Optional ByVal Point$ = ".")
numA = Replace(Replace(numA, " ", ""), IIf(Point = ".", ",", "."), "")
numB = Replace(Replace(numB, " ", ""), IIf(Point = ".", ",", "."), "")
Dim MxStr%, I&, cAdd$, em%, max&, T1&, T2&, Rep1$, Rep2$, Tmp$
Dim Ctn$(1 To 6), LCtn&(1 To 6)
T1 = InStr(numA, Point): T2 = InStr(numB, Point)
Ctn(1) = Left(numA, IIf(T1 = 0, Len(numA), T1 - 1)): LCtn(1) = Len(Ctn(1))
Ctn(2) = Left(numB, IIf(T2 = 0, Len(numB), T2 - 1)): LCtn(2) = Len(Ctn(2))
Ctn(3) = Right(numA, IIf(T1 = 0, 0, Len(numA) - T1)): LCtn(3) = Len(Ctn(3))
Ctn(4) = Right(numB, IIf(T2 = 0, 0, Len(numB) - T2)): LCtn(4) = Len(Ctn(4))
LCtn(5) = IIf(LCtn(1) > LCtn(2), LCtn(1), LCtn(2))
Ctn(1) = String(LCtn(5) - LCtn(1), "0") & Ctn(1)
Ctn(2) = String(LCtn(5) - LCtn(2), "0") & Ctn(2)
LCtn(6) = IIf(LCtn(3) > LCtn(4), LCtn(3), LCtn(4))
Ctn(3) = Ctn(3) & String(LCtn(6) - LCtn(3), "0")
Ctn(4) = Ctn(4) & String(LCtn(6) - LCtn(4), "0")
If LCtn(6) > 0 Then
numA = Ctn(3): numB = Ctn(4): max = LCtn(6): GoSub Add
Rep1 = numA
End If
numA = Ctn(1): numB = Ctn(2): max = LCtn(5): GoSub Add
Rep2 = IIf(em > 0, em, "") & numA
AddDecimal = Rep2
If LCtn(6) > 0 Then
AddDecimal = AddDecimal & IIf(Rep1 > "0", Point & Rep1, "")
End If
Exit Function
Add:
MxStr = 28
For I = max To 1 Step -1
If I < MxStr Then
MxStr = I: I = 1
Else
I = I - MxStr + 1
End If
cAdd = CDec(Mid(numA, I, MxStr)) + CDec(Mid(numB, I, MxStr)) + em
em = 0: If Len(cAdd) > MxStr Then em = Left(cAdd, 1)
Tmp = Right(cAdd, MxStr)
If LCtn(6) > 0 And Rep1 = vbNullString Then
cAdd = CDec("." & Tmp)
If Len(cAdd) = 1 Then
LCtn(6) = LCtn(6) - MxStr
numA = Left(numA, LCtn(6))
Else
LCtn(6) = LCtn(6) - Len("xx" & Tmp) + Len(cAdd)
numA = Left(numA, LCtn(6))
Mid(numA, I, MxStr) = Tmp
End If
Else
Mid(numA, I, MxStr) = Tmp
End If
Next I
Return
End Function