Beispiel #1
0
        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;
        }