Пример #1
0
        internal static bool Equal(LongIntBase A, bool AisPositive,
		                           LongIntBase B, bool BisPositive)
        {
            if (A.IsZero() && B.IsZero())
                return true;

            if (AisPositive != BisPositive)
                return false;

            return LongMath.Equal(A, B);
        }
Пример #2
0
        internal static bool Equal(LongIntBase A, bool AisPositive,
		                           short b)
        {
            if (b == 0)
                return A.IsZero();

            bool bSign = (b >= 0);
            if (AisPositive != bSign)
                return false;

            if (b < 0)
                b *= -1;

            return LongMath.Equal(A, (ushort)b);
        }
Пример #3
0
        internal static bool Equal(LongIntBase A, ushort b)
        {
            if (b == 0)
                return A.IsZero();

            if (A.Size > 2 || A.Size < 1)
                return false;

            int index = 0;
            uint Base = A.Base;
            do
            {
                if (A[index] != (ushort)(b % Base))
                    return false;

                b = (ushort)(b / Base);

                ++index;
            } while (b != 0);

            return true;
        }
Пример #4
0
        internal static LongIntBase Multiply(LongIntBase A, bool AisPositive, short b, out bool resultSign)
        {
            if (A.IsZero() || (b == 0))
            {
                resultSign = true;
                return new LongIntBase(0, A.Base, A.CoefLength);
            }

            resultSign = !(AisPositive ^ (b >= 0));

            if (b < 0)
                b *= -1;

            if (b == 1)
                return new LongIntBase(A, ConstructorMode.Copy);

            return new LongIntBase(LongMath.UShortMul(A, (ushort)b), ConstructorMode.Assign);
        }
Пример #5
0
        internal static LongIntBase Multiply(LongIntBase A, bool AisPositive,
		                                     LongIntBase B, bool BisPositive, out bool resultSign)
        {
            if (A.IsZero() || B.IsZero())
            {
                resultSign = true;
                return new LongIntBase(0, A.Base, A.CoefLength);
            }

            resultSign = !(AisPositive ^ BisPositive);
            return new LongIntBase(LongMath.Multiply(A, B), ConstructorMode.Assign);
        }
Пример #6
0
        internal static LongIntBase Divide(LongIntBase A, bool AisPositive, short b, out bool resultSign)
        {
            if (A.IsZero())
            {
                resultSign = true;
                return new LongIntBase(A);
            }

            resultSign = !((b >= 0) ^ AisPositive);

            if (b < 0)
                b *= -1;

            if (b == 1)
                return new LongIntBase(A, ConstructorMode.Copy);

            ushort r = 0;
            LongIntBase Q = new LongIntBase(A.Base);

            LongMath.UShortDiv(A, (ushort)b, out Q, out r);

            return new LongIntBase(Q, ConstructorMode.Assign);
        }
Пример #7
0
        internal static LongIntBase Divide(LongIntBase A, bool AisPositive,
		                                   LongIntBase B, bool BisPositive,
		                                   out bool resultSign)
        {
            if (A.IsZero())
            {
                resultSign = true;
                return new LongIntBase(A);
            }

            LongIntBase Q = new LongIntBase(A.Base);
            LongIntBase R = new LongIntBase(B.Base);

            LongMath.Divide(A, B, out Q, out R, true, false);

            resultSign = !(AisPositive ^ BisPositive);
            return new LongIntBase(Q, ConstructorMode.Assign);
        }
Пример #8
0
        internal static void Divide(LongIntBase A, LongIntBase B, out LongIntBase Q, out LongIntBase R, 
		                            bool useResultMaxSize, bool useRemainingMaxSize)
        {
            if (B.IsZero())
                throw new DivideByZeroException("Cannot divide by zero!");

            int Base = (int)A.Base;

            if (LongMath.Less(A, B))
            {
                Q = new LongIntBase(A.Base, A.CoefLength);
                R = new LongIntBase(A);
                return;
            }

            if (B.Size == 1)
            {
                ushort tempR = 0;
                R = new LongIntBase(A.Base, B.CoefLength);
                UShortDiv(A, B[0], out Q, out tempR);
                R[0] = tempR;
                R.Size = 1;

                return;
            }

             	//LongIntBase A = new LongIntBase(inputA, (uint)inputA.Size + 1);
            //LongIntBase B = new LongIntBase(inputB, (uint)inputB.Size + 1);

            Q = new LongIntBase(A.Base, (useResultMaxSize ? A.CoefLength : (uint)A.Size + 1) );
            R = new LongIntBase(B.Base, (useRemainingMaxSize ? B.CoefLength : (uint)B.Size + 1) );

            /*
             * create temporaty LongNUmber U, that is
             * equivalent to A
             * Maximum U size is greater than A size,
             * if we will advance A while normalizing
            */
            LongIntBase U = new LongIntBase(A, (uint)A.Size + 1);
            //U[A.Size] = 0;

            int n = B.Size;
            int m = U.Size - B.Size;

            int uJ, vJ, i;
            long temp1, temp2, temp;

            //normalization coeficient
            int scale;

            //guessed number for remaining
            long qGuess, r;

            //carries
            int borrow, carry;

            scale = (Base / ((int)B[n - 1] + 1));

            if (scale > 1)
            {
                UShortMulSafe(ref U, (ushort)scale);
                UShortMulSafe(ref B, (ushort)scale);
            }

            /*
             * Main loop in dividing
             * Every iteration gets next remaining digit
             * vJ - current shift from U, that is used for substraction
             *  (index of next digit in result)
             * uJ - index of current U digit
            */

            for (vJ = m, uJ = n + vJ; vJ >= 0; --vJ, --uJ)
            {
                long numerator = U[uJ]*(long)Base + (long)U[uJ - 1];

                qGuess = numerator / B[n - 1];
                r = numerator - qGuess*B[n - 1];

                while (r < Base)
                {
                    temp2 = B[n - 2]*qGuess;
                    temp1 = r*Base + U[uJ - 2];

                    if ((temp2 > temp1) || (qGuess == Base))
                    {
                        --qGuess;
                        r += B[n - 1];
                    }
                    else
                        break;
                }

                /*
                 * Now qGuess is correct part or is advanced with 1 to q
                 * Calculate divisor B, multiplied on qGuess from U
                 * from position vJ + i
                */
                carry = 0; borrow = 0;
                //LongIntBase uShift = U;

                //unsigned short *uShift = u + vJ;

                //looping on B digits
                for (i = 0; i < n; ++i)
                {
                    //try to get digit of product B*qGuess
                    temp1 = B[i]*qGuess + carry;

                    carry = (int)(temp1 / Base);

                    temp1 -= ((long)carry*Base);

                    //substract it from U
                    temp2 = U[i + vJ] - temp1 + borrow;
                    if (temp2 < 0)
                    {
                        U[i + vJ] = (ushort)(temp2 + Base);
                        borrow = -1;
                    }
                    else
                    {
                        U[i + vJ] = (ushort)temp2;
                        borrow = 0;
                    }
                }

                /*
                 * maybe, B that is multiplied on qQuess became bigger
                 * if yes, after multiplying carry was unused
                 * it must be substracted also
                */
                temp2 = U[i + vJ] - carry + borrow;
                if (temp2 < 0)
                {
                    U[i + vJ] = (ushort)(temp2 + Base);
                    borrow = -1;
                }
                else
                {
                    U[i + vJ] = (ushort)temp2;
                    borrow = 0;
                }

                //if division was ok, than
                if (borrow == 0)
                {
                    Q[vJ] = (ushort)qGuess;
                }
                else
                {
                    Q[vJ] = (ushort)(qGuess - 1);
                    //add one substraction
                    carry = 0;
                    for (i = 0; i < n; ++i)
                    {
                        temp = U[i + vJ] + B[i] + carry;
                        if (temp >= Base)
                        {
                            U[i + vJ] = (ushort)(temp - Base);
                            carry = 1;
                        }
                        else
                        {
                            U[i + vJ] = (ushort)temp;
                            carry = 0;
                        }
                    }
                    U[i + vJ] = (ushort)(U[i + vJ] + carry - Base);
                }
                i = U.Size - 1;
                if (i > 0)
                    while (U[i] == 0)
                    {
                        --i;
                        if (i == 0)
                            break;
                    }
                U.Size = i + 1;

            }
            if (m > 0)
                while (Q[m] == 0)
                {
                    --m;
                    if (m == 0)
                        break;
                }
            Q.Size = m + 1;

            if (scale > 1)
            {
                ushort junk = 0;
                UShortDivSafe(B, (ushort)scale, ref B, ref junk);

                LongIntBase tempR = null;
                UShortDiv(U, (ushort)scale, out tempR, out junk);

                R = new LongIntBase(tempR, (useRemainingMaxSize ? LongIntBase.MaxRange : (uint)tempR.Size + 1));
            }
            else
                R.AssignBase(U);// = U;
        }