Usually large numbers are stored as arrays of integers. Each integer is one digit. This approach allows you to multiply any number by the base power with a simple left-shift of the array.
Here is my list-based implementation (may contain errors):
def normalize(l,b): over = 0 for i,x in enumerate(l): over,l[i] = divmod(x+over,b) if over: l.append(over) return l def sum_lists(x,y,b): l = min(len(x),len(y)) res = map(operator.add,x[:l],y[:l]) if len(x) > l: res.extend(x[l:]) else: res.extend(y[l:]) return normalize(res,b) def sub_lists(x,y,b): res = map(operator.sub,x[:len(y)],y) res.extend(x[len(y):]) return normalize(res,b) def lshift(x,n): if len(x) > 1 or len(x) == 1 and x[0] != 0: return [0 for i in range(n)] + x else: return x def mult_lists(x,y,b): if min(len(x),len(y)) == 0: return [0] m = max(len(x),len(y)) if (m == 1): return normalize([x[0]*y[0]],b) else: m >>= 1 x0,x1 = x[:m],x[m:] y0,y1 = y[:m],y[m:] z0 = mult_lists(x0,y0,b) z1 = mult_lists(x1,y1,b) z2 = mult_lists(sum_lists(x0,x1,b),sum_lists(y0,y1,b),b) t1 = lshift(sub_lists(z2,sum_lists(z1,z0,b),b),m) t2 = lshift(z1,m*2) return sum_lists(sum_lists(z0,t1,b),t2,b)
sum_lists and sub_lists returns an abnormal result - a single digit may be larger than the base value. The normalize function solved this problem.
All functions expect to get a list of numbers in reverse order. For example, 12 in base 10 should be written as [2,1]. Let's take the square 9987654321.
ยป a = [1,2,3,4,5,6,7,8,9] ยป res = mult_lists(a,a,10) ยป res.reverse() ยป res [9, 7, 5, 4, 6, 1, 0, 5, 7, 7, 8, 9, 9, 7, 1, 0, 4, 1]