import java.math.BigInteger; import java.util.Random; import java.lang.Math; /** * Class FastBigInteger wraps BigInteger * endowing it with an asympototically faster * Divide and Conquer based method for multiplication. * The main() method performs some randomized tests * to determine if this asymptotic behavior * surpasses the usual multiplication method * in practical terms. **/ public class FastBigInteger{ private BigInteger N; public static final int BREAKLENGTH = 3000; public static final int MAXBITLENGTH = 10000000; public FastBigInteger(String val){ N = new BigInteger(val); } public FastBigInteger(BigInteger N){ this.N = N; } /** * Method that creates a pseudo-random * FastBigInteger of a specified length. The * random object is required so that the * results of the methods can be recreated */ public FastBigInteger(int l, Random r){ N = new BigInteger(l,r); } public String toString(){ return N.toString(); } /** Wrapper of standard addition method */ public FastBigInteger add(FastBigInteger y){ return new FastBigInteger(N.add(y.N)); } /** Wrapper of standard subtraction method */ public FastBigInteger subtract(FastBigInteger y){ return new FastBigInteger(N.subtract(y.N)); } /** Wrapper of standard multiplication method */ public FastBigInteger multiply(FastBigInteger y){ return new FastBigInteger(N.multiply(y.N)); } /** Wrapper of standard left shift method */ public FastBigInteger shiftLeft(int n){ return new FastBigInteger(N.shiftLeft(n)); } /** Wrapper of standard right shift method */ public FastBigInteger shiftRight(int n){ return new FastBigInteger(N.shiftRight(n)); } /** Wrapper of standard negate method */ public FastBigInteger negate(){ return new FastBigInteger(N.negate()); } /** Wrapper of standard absolute value method */ public FastBigInteger abs(){ return new FastBigInteger(N.abs()); } /** * The recursive, divide and conquer * fast multiplication works as follows: * Suppose we want to multiply two binary * numbers a and b. Suppose that in binary * we have a = [A1][A2], and b = [B1][B2] * where A1, A2, B1 and B2 are length-n bitstrings. * Then the following holds * a*b = (A1*2^n + A2)*(B12^n + B2) * = (A1*B1)*2^(2n) + (A1*B2 + A2*B1)*2^n + A2*B2 * = (A1*B1)*(2^(2n)+2^n) + (A1-A2)*(B2-B1)*2^n + (A2*B2)*(2^n+1) * = (A1*B1)<<(2n) + (A1*B2)<