예제 #1
0
        internal static bool Greater(LongIntBase A, LongIntBase B)
        {
            if (A.Base != B.Base)
                throw new DifferentBasesException("Attempt to compare two numbers with different bases!");

            if (A.Size < B.Size)
                return false;

            if (A.Size > B.Size)
                return true;

            int i = A.Size - 1;

            while (A[i] == B[i])
            {
                --i;
                if (i < 0)
                    break;
            }

            if (i < 0)
                return false;

            return (A[i] > B[i]);
        }
예제 #2
0
        internal static LongIntBase Add(LongIntBase A, LongIntBase B)
        {
            LongIntBase What = A, To = B;

            if (A.Size < B.Size)
            {
                What = B;
                To = A;
            }

            LongIntBase C = new LongIntBase(What.Base, System.Math.Max(What.CoefLength, To.CoefLength));
            int Base = (int)What.Base;

            int carry = 0;
            int temp;
            int i;

            for (i = 0; i < To.Size; ++i)
            {
                temp = (int)What[i] + (int)To[i] + carry;
                if (temp >= Base)
                {
                    C[i] = (ushort)(temp - Base);
                    carry = 1;
                }
                else
                {
                    C[i] = (ushort)temp;
                    carry = 0;
                }
            }

            for (; i < What.Size; ++i)
            {
                temp = What[i] + carry;
                if (temp >= Base)
                {
                    C[i] = (ushort)(temp - Base);
                    carry = 1;
                }
                else
                {
                    C[i] = (ushort)temp;
                    carry = 0;
                }
            }

            if (carry != 0)
            {
                C[i] = (ushort)carry;
                C.Size = What.Size + 1;
            }
            else
                C.Size = What.Size;

            return C;
        }
예제 #3
0
        public static void Divide(ULongIntD A, ULongIntD B, out ULongIntD Q, out ULongIntD R)
        {
            LongIntBase QNumber = new LongIntBase(A.Base);
            LongIntBase RNumber = new LongIntBase(B.Base);

            LongMath.Divide(A, B, out QNumber, out RNumber, true, true);
            Q = new ULongIntD(QNumber, ConstructorMode.Assign);
            R = new ULongIntD(RNumber, ConstructorMode.Assign);
        }
예제 #4
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);
        }
예제 #5
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);
        }
예제 #6
0
        internal static bool Equal(LongIntBase A, LongIntBase B)
        {
            if (A.Base != B.Base)
                return false;

            if (A.Size != B.Size)
                return false;

            int i = 0;
            while (A[i] == B[i])
            {
                ++i;
                if (i >= A.Size)
                    break;
            }
            return (i == A.Size);
        }
예제 #7
0
        internal static LongIntBase Add(LongIntBase A, ushort b)
        {
            LongIntBase C = new LongIntBase(A);
            uint Base = A.Base;

            int index = 0;
            uint carry = 0;

            uint temp = (uint)C[0] + (uint)b;
            if (temp >= Base)
            {
                C[0] = (ushort)(temp - Base);
                carry = 1;
            }
            else
            {
                C[0] = (ushort)temp;
                carry = 0;
            }

            ++index;

            while (carry != 0)
            {
                temp = C[index] + carry;
                if (temp >= Base)
                {
                    C[index] = (ushort)(temp - Base);
                    carry = 1;
                }
                else
                {
                    C[index] = (ushort)temp;
                    carry = 0;
                }

                ++index;
            }

            if (index > A.Size)
                C.Size = index;
            else
                C.Size = A.Size;

            return C;
        }
예제 #8
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;
        }
예제 #9
0
        internal static bool Greater(LongIntBase A, ushort b)
        {
            LongIntBase temp = new LongIntBase(b, A.Base, 2);

            return Greater(A, temp);
        }
예제 #10
0
        internal static void UShortMulSafe(ref LongIntBase A, ushort B)
        {
            uint Base = A.Base;

            int i = 0;
            long temp, carry = 0;
            long b = B;

            for (i = 0; i < A.Size; ++i)
            {
                temp = A[i]*b + carry;
                carry = temp / Base;

                A[i] = (ushort)(temp - (carry*Base));
            }

            if (carry != 0)
            {
                A[i] = (ushort)carry;
                A.Size++;
            }
        }
예제 #11
0
        internal static LongIntBase UShortMul(LongIntBase A, ushort B)
        {
            LongIntBase C = new LongIntBase(A.Base, A.CoefLength + 1);
            uint Base = A.Base;

            int i = 0;
            long temp, carry = 0;
            long b = B;

            for (i = 0; i < A.Size; ++i)
            {
                temp = A[i]*b + carry;
                carry = temp / Base;

                C[i] = (ushort)(temp - (carry*Base));
            }

            if (carry != 0)
            {
                C[i] = (ushort)carry;
                C.Size = A.Size + 1;
            }
            else
                C.Size = A.Size;

            return C;
        }
예제 #12
0
        internal static LongIntBase Multiply(LongIntBase A, LongIntBase B)
        {
            LongIntBase C = new LongIntBase(A.Base, System.Math.Max(A.CoefLength, B.CoefLength) + 1);
            uint Base = A.Base;

            int i, j;
            long temp, carry;

            for (i = 0; i < A.Size; ++i)
            {
                carry = 0;
                for (j = 0; j < B.Size; ++j)
                {
                    temp = A[i];
                    temp *= B[j];
                    temp += C[i + j] + carry;

                    carry = temp / Base;
                    C[i + j] = (ushort)(temp - (carry * Base));
                }
                C[i + j] = (ushort)carry;
            }

            i = A.Size + B.Size - 1;
            if (i > 0)
                while (C[i] == 0)
                {
                    --i;
                    if (i == 0)
                        break;
                }

            C.Size = i + 1;

            return C;
        }
예제 #13
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);
        }
예제 #14
0
        internal static LongIntBase InnerPower(LongIntBase A, ulong n)
        {
            LongIntBase X = new LongIntBase(A);
            LongIntBase R = new LongIntBase(A.Base, X.CoefLength);
            R[0] = 1;

            while (n != 0)
            {
                if ((n & 1) == 1)
                    R = Multiply(R, X);

                n >>= 1;

                X = InnerSqr(X);
            }

            return R;
        }
예제 #15
0
        internal static bool Less(LongIntBase A, bool AisPositive,
		                          short b)
        {
            bool bSign = (b >= 0);

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

            if (AisPositive == bSign)
            {
                if (AisPositive)
                    return LongMath.Less(A, (ushort)b);
                else
                    return LongMath.Greater(A, (ushort)b);
            }

            if (AisPositive)
                return false;

            return true;
        }
예제 #16
0
        internal static LongIntBase SubstractSafe(LongIntBase From, ushort What)
        {
            LongIntBase C = new LongIntBase(From);
            int Base = (int)From.Base;

            int i = 0;
            int carry = 0;

            int temp = From[0] - (int)What;

            if (temp < 0)
            {
                C[0] = (ushort)(temp + Base);
                carry = -1;
            }
            else
            {
                C[0] = (ushort)temp;
                carry = 0;
            }
            ++i;

            while (carry != 0)
            {
                temp = From[i] + carry;
                if (temp < 0)
                {
                    C[i] = (ushort)(temp + Base);
                    carry = -1;
                }
                else
                {
                    C[i] = (ushort)temp;
                    carry = 0;
                }

                ++i;
            }

            i = From.Size - 1;
            if (i > 0)
                while (C[i] == 0)
                {
                    --i;
                    if (i == 0)
                        break;
                }

            C.Size = i + 1;

            return C;
        }
예제 #17
0
        internal static LongIntBase SubstractSafe(LongIntBase From, LongIntBase What)
        {
            LongIntBase C = new LongIntBase(From.Base, System.Math.Max(From.CoefLength, What.CoefLength));
            uint Base = From.Base;

            int i;
            int temp;
            int carry = 0;

            for (i = 0; i < What.Size; ++i)
            {
                temp = From[i] - What[i] + carry;
                if (temp < 0)
                {
                    C[i] = (ushort)(temp + Base);
                    carry = -1;
                }
                else
                {
                    C[i] = (ushort)temp;
                    carry = 0;
                }
            }

            for (; i < From.Size; ++i)
            {
                temp = From[i] + carry;
                if (temp < 0)
                {
                    C[i] = (ushort)(temp + Base);
                    carry = -1;
                }
                else
                {
                    C[i] = (ushort)temp;
                    carry = 0;
                }
            }

            i = From.Size - 1;
            if (i > 0)
                while (C[i] == 0)
                {
                    --i;
                    if (i == 0)
                        break;
                }

            C.Size = i + 1;
            return C;
        }
예제 #18
0
        internal static LongIntBase Substract(LongIntBase A, bool AisPositive,
		                                      short b, out bool resultSign)
        {
            bool BisPositive = (b >= 0);

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

            if (AisPositive != BisPositive)
            {
                // (A + B) or (-A - B) == -(A + B)
                resultSign = AisPositive;
                return new LongIntBase(LongMath.Add(A, (ushort)b), ConstructorMode.Assign);
            }
            else
            {
                /*
                 * Possible variants:
                 * (A - B)  ==
                 *
                 * A > B  ->  A - B
                 * A == B ->  0
                 * A < B  ->  -(B - A)
                */
                resultSign = true;

                if (LongMath.Equal(A, (ushort)b))
                    return new LongIntBase(0, A.Base, LongIntBase.MaxRange);

                if (AisPositive == false)
                    resultSign = !resultSign;

                if (Greater(A, (ushort)b))
                    return new LongIntBase(LongMath.SubstractSafe(A, (ushort)b), ConstructorMode.Assign);

                resultSign = false;

                if (AisPositive == false)
                    resultSign = !resultSign;

                return new LongIntBase(LongMath.SubstractSafe((ushort)b, A), ConstructorMode.Assign);
            }
        }
예제 #19
0
        internal static LongIntBase Substract(LongIntBase A, bool AisPositive, 
		                                      LongIntBase B, bool BisPositive,
		                                      out bool resultSign)
        {
            if (AisPositive != BisPositive)
            {
                // (A + B) or (-A - B) == -(A + B)
                resultSign = AisPositive;
                return new LongIntBase(LongMath.Add(A, B), ConstructorMode.Assign);
            }
            else
            {
                /*
                 * Possible variants:
                 * (A - B)  ==
                 *
                 * A > B  ->  A - B
                 * A == B ->  0
                 * A < B  ->  -(B - A)
                */

                resultSign = true;

                if (LongMath.Equal(A, B))
                    return new LongIntBase(0, A.Base, LongIntBase.MaxRange);

                resultSign = AisPositive;

                if (Greater(A, B))
                    return new LongIntBase(LongMath.SubstractSafe(A, B), ConstructorMode.Assign);

                resultSign = !AisPositive;

                return new LongIntBase(LongMath.SubstractSafe(B, A), ConstructorMode.Assign);
            }
        }
예제 #20
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);
        }
예제 #21
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);
        }
예제 #22
0
        internal static bool Less(LongIntBase A, ushort b)
        {
            LongIntBase temp = new LongIntBase(b, A.Base, 2);

            return Less(A, temp);
        }
예제 #23
0
        internal static bool Less(LongIntBase A, bool AisPositive,
		                          LongIntBase B, bool BisPositive)
        {
            if (AisPositive == BisPositive)
            {
                if (AisPositive)
                    return LongMath.Less(A, B);
                else
                    return LongMath.Greater(A, B);
            }

            if (AisPositive)
                return false;

            return true;
        }
예제 #24
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);
        }
예제 #25
0
        internal static void UShortDiv(LongIntBase A, ushort B, out LongIntBase Q, out ushort R)
        {
            // division with new result
            uint Base = A.Base;
            Q = new LongIntBase(A.Base, A.CoefLength);

            long r = 0;
            int i;
            long temp, b = B;

            for (i = A.Size - 1; i >= 0; --i)
            {
                temp = (r * Base) + A[i];
                Q[i] = (ushort)(temp / b);
                r = temp - Q[i]*b;
            }

            //r - remaining from division
            R = (ushort)r;

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

            Q.Size = i + 1;
        }
예제 #26
0
        internal static void UShortDivSafe(LongIntBase A, ushort B, ref LongIntBase Q, ref ushort R)
        {
            // division in place
            uint Base = A.Base;

            long r = 0;
            int i;
            long temp, b = B;

            for (i = A.Size - 1; i >= 0; --i)
            {
                temp = (r * Base) + A[i];
                Q[i] = (ushort)(temp / b);
                r = temp - Q[i]*b;
            }

            //r - remaining from division
            R = (ushort)r;

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

            Q.Size = i + 1;
        }
예제 #27
0
        internal static void Increment(ref LongIntBase A, ushort incrementValue)
        {
            int index = 0;
            int carry = 0;
            uint Base = A.Base;

            int temp = A[0] + incrementValue + carry;
            if (temp >= Base)
            {
                A[0] = (ushort)(temp - Base);
                carry = 1;
            }
            else
            {
                A[0] = (ushort)temp;
                carry = 0;
            }

            ++index;

            while (carry != 0)
            {
                temp = A[index] + carry;
                if (temp >= Base)
                {
                    A[index] = (ushort)(temp - Base);
                    carry = 1;
                }
                else
                {
                    A[index] = (ushort)temp;
                    carry = 0;
                }

                ++index;
            }

            if (index > A.Size)
                A.Size = index;
        }
예제 #28
0
        internal static LongIntBase Mod(LongIntBase A, LongIntBase B)
        {
            LongIntBase Q = new LongIntBase(A.Base);
            LongIntBase R = new LongIntBase(B.Base);

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

            return new LongIntBase(R, ConstructorMode.Assign);
        }
예제 #29
0
        internal static LongIntBase SubstractSafe(ushort From, LongIntBase What)
        {
            LongIntBase C = new LongIntBase(What);

            int temp = From - C[0];
            C[0] = (ushort)temp;

            return C;
        }
예제 #30
0
        internal static ushort Mod(LongIntBase A, ushort b)
        {
            ushort r = 0;
            LongIntBase Q = new LongIntBase(A.Base);

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

            return r;
        }