static private void FastMul(BigNumber aa, BigNumber bb, BigNumber rr) { int ii, k, nexp, sign; BigNumber M_ain = new BigNumber(); BigNumber M_bin = new BigNumber(); BigNumber.Copy(aa, M_ain); BigNumber.Copy(bb, M_bin); int size_flag = GetSizeofInt(); int bit_limit = 8 * size_flag + 1; sign = M_ain.signum * M_bin.signum; nexp = M_ain.exponent + M_bin.exponent; if (M_ain.dataLength >= M_bin.dataLength) { ii = M_ain.dataLength; } else { ii = M_bin.dataLength; } ii = (ii + 1) >> 1; ii = NextPowerOfTwo(ii); k = 2 * ii; /* required size of result, in bytes */ BigNumber.Pad(M_ain, k); /* fill out the data so the number of */ BigNumber.Pad(M_bin, k); /* bytes is an exact power of 2 */ if (k > rr.mantissa.Length) { BigNumber.Expand(rr, (k + 32)); } BigNumber.FastMulFFT(rr.mantissa, M_ain.mantissa, M_bin.mantissa, ii); rr.signum = (sbyte)sign; rr.exponent = nexp; rr.dataLength = 4 * ii; BigNumber.Normalize(rr); }
/// <summary> /// normalize number /// </summary> /// <param name="atm"></param> static private void Normalize(BigNumber atm) { if (atm.signum == 0) { return; } int ucp = 0; int i; int index; int datalength = atm.dataLength; int exponent = atm.exponent; byte numdiv = 0, numrem = 0, numrem2 = 0; BigNumber.Pad(atm, datalength + 3); // remove leading zeroes while (true) { // extract first 2 nibbles Unpack(atm.mantissa[0], ref numdiv, ref numrem); // if first digit is greater 1 we are done if (numdiv >= 1) { break; } // otherwise we have leading zeroes index = (datalength + 1) >> 1; if (numrem == 0) // both nibbles are 0 { i = 0; ucp = 0; while (true) { if (atm.mantissa[ucp] != 0) { break; } ucp++; i++; } byte[] copy = new byte[atm.mantissa.Length]; Array.Copy(atm.mantissa, ucp, copy, 0, (index + 1 - i)); atm.mantissa = copy; datalength -= 2 * i; exponent -= 2 * i; } else { for (i = 0; i < index; i++) { Unpack(atm.mantissa[i + 1], ref numdiv, ref numrem2); atm.mantissa[i] = (byte)(10 * numrem + numdiv); numrem = numrem2; } datalength--; exponent--; } } // remove trailing zeroes while (true) { index = ((datalength + 1) >> 1) - 1; if ((datalength & 1) == 0) /* back-up full bytes at a time if the */ { /* current length is an even number */ ucp = index; if (atm.mantissa[ucp] == 0) { while (true) { datalength -= 2; index--; ucp--; if (atm.mantissa[ucp] != 0) { break; } } } } Unpack(atm.mantissa[index], ref numdiv, ref numrem); if (numrem != 0) /* last digit non-zero, all done */ { break; } if ((datalength & 1) != 0) /* if odd, then first char must be non-zero */ { if (numdiv != 0) { break; } } if (datalength == 1) { atm.signum = 0; exponent = 0; break; } datalength--; } atm.dataLength = datalength; atm.exponent = exponent; }