0

I have implemented Karatsuba multiplication in Python.

The code and pseudocode are as follow:

def karatsuba(x, y):
    """
    Input: two n-digit positive integers x and y. 
    Output: the product x·y. 
    Assumption: n is a power of 2. (NOT assuming this)

    if n =1  then                   // base case
        compute x·y in one step and return the result
    else 
        a,b := first and second halves of x 
        c,d := first and second halves of y 
        compute p := a + b and q := c + d using grade-school addition 
        recursively compute ac := a·c, bd := b·d, and pq := p·q 
        compute adbc := pqacbd using grade-school addition 
        compute 10n ·ac + 10n/2 ·adbc + bd using grade-school addition and return the result
    """

    str_x = str(x)
    str_y = str(y)
    if len(str_x) == 1 or len(str_y) == 1:
        return x*y
    else:
        n = max(len(str_x), len(str_y))
        n_half = int(n / 2)
        
        a, b = x // 10**n_half, x % 10**n_half
        c, d = y // 10**n_half, y % 10**n_half
        
        p = a + b
        q = c + d
    
        ac = karatsuba(a, c)
        bd = karatsuba(b, c)
        pq = karatsuba(p, q)
        
        adbc = pq - ac - bd
        
        return 10**(2*n_half) * ac + 10**n_half * adbc + bd

When I do the multiplication of very large numbers, my code is failing.

Here is an example:

>>> a = 3141592653589793238462643383279502884197169399375105820974944592
>>> b = 2718281828459045235360287471352662497757247093699959574966967627
>>> mul_karatsuba = karatsuba(a, b)
>>> mul_builtin = a * b
>>> mul_karatsuba == mul_builtin
False
>>> mul_karatsuba
8945653667798941823160787739573304887842903322205621858854691873536479127635014727457078833467629169552143732979528067839403974
>>> mul_builtin
8539734222673567065463550869546574495034888535765114961879601127067743044893204848617875072216249073013374895871952806582723184

I am not able to find what exactly is wrong with my code. I have coded everything according to mentioned pseudocode.

Can you please help me?

skad00sh
  • 171
  • 11
  • this should be n//2 at least ? – Christian Sloper Feb 04 '21 at 17:55
  • 4
    `bd = karatsuba(b, c)` doesn't look like it's quite what you intended. – jasonharper Feb 04 '21 at 18:35
  • 1
    why are you using bigint pow function to compute bigint multiplication ? Karatsuba is a multiplication and power (`**`) is higher function that usually use multiplication inside... so instead of speeding multiplication you will end up with slower one... Also converting bigint operands into string is much slower than all of this combined ... not coding in python but for bigint is usual to have info about how many bits are used (like `log2(x)` but it is obtained in `O(1)`) also using powers of 2 can get rid of all `**`, and `/,%` operations and use just bitshifts – Spektre Feb 04 '21 at 19:57
  • @jasonharper thanks! solved the problem. It was nothing but my negligence :( – skad00sh Feb 05 '21 at 03:17
  • Also, @Spektre I am not understanding what you are trying to say. Maybe because I am very beginner at programming. Can you please elaborate? – skad00sh Feb 05 '21 at 03:18
  • 1
    @skad00sh Its like you would want to compute simple `a+b` by using much more complicated functions like `*,/,log,exp,pow` on the same bitwidth and expecting it would be faster. Another problem is if you are computing bigint operation `*` by using again the same `*` on the same bitwidth inside then you do not really computing `*` you just using the build in one behind the scenes. Implementations of math operations should always use lower operations if possible but certainly not higher ones. Btw if you would implementing full math this way such code would crash with Stack Overflow – Spektre Feb 05 '21 at 07:39
  • Ohh! Understood! Thanks! – skad00sh Feb 08 '21 at 05:59

0 Answers0