BeginPackage["CSM`Bignum`"]

B::usage = "B is the base of the positional number system."
carry::usage = "carry[z] is the carry into the next digit."
rem::usage = "rem[z] is the remainder after removal of the carry."
digit::usage = "digit[a, i] is the ith digit of a."
newNumber::usage = "newNumber[n] is the skeleton of a number of length n."
length::usage = "length[a] is the number of digits of a."

plus::usage = "plus[a, b] is the sum of the numbers a and b."

Begin["`Private`"]

B = 10; (* default *)

newNumber[n_Integer?NonNegative] := Table[0, {n}]

length[a_] := Length[a]

digit[a_, i_Integer?NonNegative] := a[[i+1]]

(* for assignments: *)

digit/: (digit[a_, i_] = neu_) := (a[[i+1]] = neu)

carry[z_Integer] := Quotient[z, B]

rem[z_Integer] := Mod[z, B]

plus[a_, b_] := plus[b, a] /; length[a] < length[b]

plus[a_, b_] :=
    Module[{c, n = length[a], m = length[b], i, d = 0},
        c = newNumber[n+1];
        Do[ d = digit[a, i] + digit[b, i] + carry[d];
            digit[c, i] = rem[d],
           {i, 0, m-1} ];
        Do[ d = digit[a, i] + carry[d];
            digit[c, i] = rem[d],
           {i, m, n-1} ];
        digit[c, n] = carry[d];
        If[ digit[c, n] == 0, c = Drop[c, -1] ]; (* normalize *)
        c
    ]

End[]

EndPackage[]
