Exemplo n.º 1
0
        /// <summary>
        /// Schoolbook division algorithm
        /// </summary>
        /// <param name="n1"></param>
        /// <param name="n2"></param>
        /// <param name="Q"></param>
        /// <param name="R"></param>
        private static void Div_32(BigInt n1, BigInt n2, BigInt Q, BigInt R)
        {
            int digitsN1 = n1.GetMSD() + 1;
            int digitsN2 = n2.GetMSD() + 1;

            //n2 is bigger than n1
            if (digitsN1 < digitsN2)
            {
                R.AssignInt(n1);
                Q.Zero();
                return;
            }

            if (digitsN1 == digitsN2)
            {
                //n2 is bigger than n1
                if (LtInt(n1, n2))
                {
                    R.AssignInt(n1);
                    Q.Zero();
                    return;
                }

                //n2 >= n1, but less the 2x n1 (initial conditions make this certain)
                Q.Zero();
                Q.digitArray[0] = 1;
                R.Assign(n1);
                R.SubInternalBits(n2.digitArray);
                return;
            }

            int digits = digitsN1 - (digitsN2 + 1);

            //Algorithm Div_31 can be used to get the answer in O(n) time.
            if (digits == 0)
            {
                Div_31(n1, n2, Q, R);
                return;
            }

            BigInt n1New = DigitShiftRight(n1, digits);
            BigInt s = DigitTruncate(n1, digits);

            BigInt Q2 = new BigInt(n1, n1.pres, true);
            BigInt R2 = new BigInt(n1, n1.pres, true);

            Div_31(n1New, n2, Q2, R2);

            R2.DigitShiftSelfLeft(digits);
            R2.Add(s);

            Div_32(R2, n2, Q, R);

            Q2.DigitShiftSelfLeft(digits);
            Q.Add(Q2);
        }