As a side benefit this can bypass the sizeof(int64) limitation, so any number can be added. Doesn't handle decimals.
This function works left-to-right.
Code: Select all
; This function adds 2 strings of numbers.
; Unlike using '+', this can handle an infinite number of digits.
MsgBox add("287490258693746268716387136012489723476264566625371635623536"
, "384928346284682647082634702746284751865308301827368126730876")
;= 672418604978428915799021838758774475341572868452739762354412
/* Test Code
loop 10000
if a := A_Index
loop 10000
if b := A_Index
if (a + b) != add(a, b)
MsgBox a ", " b "`n" add(a, b)
MsgBox 'done'
*/
add(a, b) {
r := "0" ; result
a := Trim(a)
b := Trim(b)
c := 0 ; carry
h := Max(StrLen(a), StrLen(b))
l := Min(StrLen(a), StrLen(b))
; Indexing functions
getA(i) => (StrLen(a) >= StrLen(b) ? SubStr(a, i, 1) : (i-h+l > 0) ? SubStr(a, i-h+l, 1) : 0)
getB(i) => (StrLen(b) >= StrLen(a) ? SubStr(b, i, 1) : (i-h+l > 0) ? SubStr(b, i-h+l, 1) : 0)
last() => SubStr(r, -1, 1)
inc() => (r := (SubStr(r, 1, -1) . last() + 1))
Loop h {
n := getA(A_Index) + getB(A_Index)
if (n > 9) {
inc() ; Increment the current result.
loop c ; For every carried 9 turn it to a 10.
r .= 0, c-- ; We already did the left-most increment via inc().
r .= mod(n, 10) ; Append the right most digit.
}
if (n = 9) {
c++ ; Can't do anything here, we don't know if a carry might cascade.
}
if (n < 9) {
loop c ; Since n < 9, append all the saved 9's.
r .= 9, c--
r .= n
}
}
loop c ; Append any remaining 9's we were unsure about.
r .= 9
return LTrim(r, "0")
}