The Karatsuba algorithm was the first multiplication algorithm asymptotically faster than the quadratic "grade school" algorithm. The Toom–Cook algorithm is a faster generalization of Karatsuba's method, and the Schönhage–Strassen algorithm is even faster, for sufficiently large n. Source: https://en.wikipedia.org/wiki/Karatsuba_algorithm
Pseudocode:
procedure karatsuba(num1, num2)
if (num1 < 10) or (num2 < 10)
return num1*num2
// calculates the size of the numbers
M = max(size_base10(num1), size_base10(num2))
N = M/2
// split the digit sequences about the middle
high1, low1 = split_at(num1, N)
high2, low2 = split_at(num2, N)
// 3 calls made to numbers approximately half the size
z0 = karatsuba(low1,low2)
z1 = karatsuba((low1+high1),(low2+high2))
z2 = karatsuba(high1,high2)
return (z2*10^(2*N))+((z1-z2-z0)*10^(N))+(z0)
Implementation:
public static BigInteger karatsuba(BigInteger x, BigInteger y) {
// cutoff to brute force
int M = Math.max(x.bitLength(), y.bitLength());
if (M <= 2000) return x.multiply(y); // optimize this parameter
// number of bits divided by 2, rounded up
int N = (M / 2) + (M % 2);
// x = a + 2^N b, y = c + 2^N d
// x = low1 + 2^N high1, y = low2 + 2^N high2
BigInteger high1 = x.shiftRight(N);
BigInteger low1 = x.subtract(high1.shiftLeft(N));
BigInteger high2 = y.shiftRight(N);
BigInteger low2 = y.subtract(high2.shiftLeft(N));
// compute sub-expressions
BigInteger z0 = karatsuba(low1, low2);
BigInteger z1 = karatsuba(low1.add(high1), low2.add(high2));
BigInteger z2 = karatsuba(high1, high2);
return z0.add(z1.subtract(z0).subtract(z2).shiftLeft(N)).add(z2.shiftLeft(2*N));
}
Source: http://introcs.cs.princeton.edu/java/99crypto/Karatsuba.java.html
No comments:
Post a Comment