DivMod() public static method

Divides one big integer represented by it's digits on another one big ingeter. Reminder is always filled (but not the result).
public static DivMod ( uint digits1, uint length1, uint int2, uint divRes, uint &modRes ) : uint
digits1 uint First big integer digits.
length1 uint First big integer length.
int2 uint Second integer.
divRes uint Div result (can be null - not filled in this case).
modRes uint Remainder (always filled).
return uint
示例#1
0
        /// <summary>
        /// Converts digits from internal representaion into given base.
        /// </summary>
        /// <param name="digits">Big integer digits.</param>
        /// <param name="length">Big integer length.</param>
        /// <param name="numberBase">Base to use for output.</param>
        /// <param name="outputLength">Calculated output length (will be corrected inside).</param>
        /// <returns>Conversion result (later will be transformed to string).</returns>
        override public uint[] ToString(uint[] digits, uint length, uint numberBase, ref uint outputLength)
        {
            uint[] outputArray = base.ToString(digits, length, numberBase, ref outputLength);

            // Maybe base method already converted this number
            if (outputArray != null)
            {
                return(outputArray);
            }

            // Create an output array for storing of number in other base
            outputArray = new uint[outputLength + 1];

            // Make a copy of initial data
            uint[] digitsCopy = new uint[length];
            Array.Copy(digits, digitsCopy, length);

            // Calculate output numbers by dividing
            uint outputIndex;

            for (outputIndex = 0; length > 0; ++outputIndex)
            {
                length = DigitOpHelper.DivMod(digitsCopy, length, numberBase, digitsCopy, out outputArray[outputIndex]);
            }

            outputLength = outputIndex;
            return(outputArray);
        }
示例#2
0
        /// <summary>
        /// Divides two big integers.
        /// Also modifies <paramref name="digitsPtr1" /> and <paramref name="length1"/> (it will contain remainder).
        /// </summary>
        /// <param name="digitsPtr1">First big integer digits.</param>
        /// <param name="digitsBufferPtr1">Buffer for first big integer digits. May also contain remainder.</param>
        /// <param name="length1">First big integer length.</param>
        /// <param name="digitsPtr2">Second big integer digits.</param>
        /// <param name="digitsBufferPtr2">Buffer for second big integer digits. Only temporarily used.</param>
        /// <param name="length2">Second big integer length.</param>
        /// <param name="digitsResPtr">Resulting big integer digits.</param>
        /// <param name="resultFlags">Which operation results to return.</param>
        /// <param name="cmpResult">Big integers comparsion result (pass -2 if omitted).</param>
        /// <returns>Resulting big integer length.</returns>
        virtual unsafe public uint DivMod(
            uint *digitsPtr1,
            uint *digitsBufferPtr1,
            ref uint length1,
            uint *digitsPtr2,
            uint *digitsBufferPtr2,
            uint length2,
            uint *digitsResPtr,
            DivModResultFlags resultFlags,
            int cmpResult)
        {
            // Base implementation covers some special cases

            bool divNeeded = (resultFlags & DivModResultFlags.Div) != 0;
            bool modNeeded = (resultFlags & DivModResultFlags.Mod) != 0;

            //
            // Special cases
            //

            // Case when length1 == 0
            if (length1 == 0)
            {
                return(0);
            }

            // Case when both lengths are 1
            if (length1 == 1 && length2 == 1)
            {
                if (divNeeded)
                {
                    *digitsResPtr = *digitsPtr1 / *digitsPtr2;
                    if (*digitsResPtr == 0)
                    {
                        length2 = 0;
                    }
                }
                if (modNeeded)
                {
                    *digitsBufferPtr1 = *digitsPtr1 % *digitsPtr2;
                    if (*digitsBufferPtr1 == 0)
                    {
                        length1 = 0;
                    }
                }

                return(length2);
            }

            // Compare digits first (if was not previously compared)
            if (cmpResult == -2)
            {
                cmpResult = DigitOpHelper.Cmp(digitsPtr1, length1, digitsPtr2, length2);
            }

            // Case when first value is smaller then the second one - we will have remainder only
            if (cmpResult < 0)
            {
                // Maybe we should copy first digits into remainder (if remainder is needed at all)
                if (modNeeded)
                {
                    DigitHelper.DigitsBlockCopy(digitsPtr1, digitsBufferPtr1, length1);
                }

                // Zero as division result
                return(0);
            }

            // Case when values are equal
            if (cmpResult == 0)
            {
                // Maybe remainder must be marked as empty
                if (modNeeded)
                {
                    length1 = 0;
                }

                // One as division result
                if (divNeeded)
                {
                    *digitsResPtr = 1;
                }

                return(1);
            }

            // Case when second length equals to 1
            if (length2 == 1)
            {
                // Call method basing on fact if div is needed
                uint modRes;
                if (divNeeded)
                {
                    length2 = DigitOpHelper.DivMod(digitsPtr1, length1, *digitsPtr2, digitsResPtr, out modRes);
                }
                else
                {
                    modRes = DigitOpHelper.Mod(digitsPtr1, length1, *digitsPtr2);
                }

                // Maybe save mod result
                if (modNeeded)
                {
                    if (modRes != 0)
                    {
                        length1 = 1;
                        *digitsBufferPtr1 = modRes;
                    }
                    else
                    {
                        length1 = 0;
                    }
                }

                return(length2);
            }


            // This is regular case, not special
            return(uint.MaxValue);
        }