Search code examples
pythonalgorithmkaratsuba

Karatsuba algorithm, slight inaccuracy


I've spent a while trying to implement Karatsuba's algorithm in Python and I'm getting close though when I try to multiply two larger numbers (over ~10^15), my result starts to get inaccurate. I can't figure out why.

Side question: Would there be a way for my base case to be "both (instead of either) x and y are strictly less (instead of less) than 10"


def karatsuba(x, y):
    # 1. Split ints

    if x <= 10 or y <= 10:
        #Base case
        return x * y

    n_x = ceil(log(x, 10))  # Nb of digits in x
    n_y = ceil(log(y, 10))

    n = max(n_x, n_y)

    b = int(x % (10 ** (n // 2)))
    a = int(x / (10 ** (n // 2)))
    d = int(y % (10 ** (n // 2)))
    c = int(y / (10 ** (n // 2)))

    # 2. Recursive calls

    ac = karatsuba(a, c)
    bd = karatsuba(b, d)
    kara = karatsuba((a + b), (c + d))

    res = ac * (10 ** (2*(n//2))) + (kara - ac - bd) * (10 ** (n//2)) + bd

    return res

Example :

x = 151222321858446622145369417738339374
y = 875336699541236667457869597252254524
karatsuba(x, y)

returns:

132370448112535269852891372864998437604548273605778561898354233338827976

instead of:

132370448112535277024334963430875927265604725663292579898354233338827976

Solution

  • You lose precision by going through float due to your / divisions. Use // instead. Then you also don't need to convert back to int. Better yet, use divmod:

        N = 10 ** (n // 2)
        a, b = divmod(x, N)
        c, d = divmod(y, N)