public FastInt multiply(FastInt val) {
int n = makePowerOfTwo(Math.max(mag.length,val.mag.length))*2;
logN = logBaseTwo(n); // Log of n base 2
reverse = reverseArray(n,logN); // initialize reversal lookup table
int signResult = signum * val.signum;
int[] A = padWithZeros(mag,n); // copies mag into A padded w/ 0's
int[] B = padWithZeros(val.mag,n); // copies val.mag into B padded w/ 0's
int[] root = rootsOfUnity(n); // creates all n roots of unity
FFT(A,root,n); // Leaves FFT result in A
FFT(B,root,n); // Leaves FFT result in B
for (int i=0; i<n; i++)
A[i] = (int) (((long)A[i]*B[i]) % P); // Component-wise multiply
reverseRoots(root); // Reverse roots to create inverse roots
inverseFFT(A,root,n); // Leaves inverse FFT result in A
propagateCarries(A); // Convert A to right no. of bits/entry
return new FastInt(signResult,A);
}