Esempio n. 1
0
        internal void SubtractPositive(Integer Result, Integer ToSub)
        {
            if (ToSub.IsULong())
            {
                SubtractULong(Result, ToSub.GetAsULong());
                return;
            }

            if (ToSub.GetIndex() > Result.GetIndex())
            {
                throw(new Exception("In Subtract() ToSub.Index > Index."));
            }

            int Max = ToSub.GetIndex();

            for (int Count = 0; Count <= Max; Count++)
            {
                SignedD[Count] = (long)Result.GetD(Count) - (long)ToSub.GetD(Count);
            }

            Max = Result.GetIndex();
            for (int Count = ToSub.GetIndex() + 1; Count <= Max; Count++)
            {
                SignedD[Count] = (long)Result.GetD(Count);
            }

            Max = Result.GetIndex();
            for (int Count = 0; Count < Max; Count++)
            {
                if (SignedD[Count] < 0)
                {
                    SignedD[Count] += (long)0xFFFFFFFF + 1;
                    SignedD[Count + 1]--;
                }
            }

            if (SignedD[Result.GetIndex()] < 0)
            {
                throw(new Exception("Subtract() SignedD[Index] < 0."));
            }

            Max = Result.GetIndex();
            for (int Count = 0; Count <= Max; Count++)
            {
                Result.SetD(Count, (ulong)SignedD[Count]);
            }

            for (int Count = Result.GetIndex(); Count >= 0; Count--)
            {
                if (Result.GetD(Count) != 0)
                {
                    Result.SetIndex(Count);
                    return;
                }
            }

            // If it never found a non-zero digit it would get down to here.
            Result.SetIndex(0);
        }
Esempio n. 2
0
        // This is an optimization for multiplying when
        // only the top digit of a number has been set and
        // all of the other digits are zero.
        internal void MultiplyTop(Integer Result, Integer ToMul)
        {
            // try
            // {
            int TotalIndex = Result.GetIndex() + ToMul.GetIndex();

            if (TotalIndex >= Integer.DigitArraySize)
            {
                throw(new Exception("MultiplyTop() overflow."));
            }

            // Just like Multiply() except that all the other
            // rows are zero:
            int ToMulIndex  = ToMul.GetIndex();
            int ResultIndex = Result.GetIndex();

            for (int Column = 0; Column <= ToMulIndex; Column++)
            {
                M[Column + ResultIndex, ResultIndex] = Result.GetD(ResultIndex) * ToMul.GetD(Column);
            }

            for (int Column = 0; Column < ResultIndex; Column++)
            {
                Result.SetD(Column, 0);
            }

            ulong Carry = 0;

            for (int Column = 0; Column <= ToMulIndex; Column++)
            {
                ulong Total = M[Column + ResultIndex, ResultIndex] + Carry;
                Result.SetD(Column + ResultIndex, Total & 0xFFFFFFFF);
                Carry = Total >> 32;
            }

            Result.SetIndex(TotalIndex);
            if (Carry != 0)
            {
                Result.SetIndex(Result.GetIndex() + 1);
                if (Result.GetIndex() >= Integer.DigitArraySize)
                {
                    throw(new Exception("MultiplyTop() overflow."));
                }

                Result.SetD(Result.GetIndex(), Carry);
            }

            /*
             * }
             * catch( Exception ) // Except )
             * {
             * // "Exception in MultiplyTop: " + Except.Message
             * }
             */
        }
Esempio n. 3
0
        internal int MultiplyUIntFromCopy(Integer Result, Integer FromCopy, ulong ToMul)
        {
            int FromCopyIndex = FromCopy.GetIndex();

            Result.SetIndex(FromCopyIndex);
            for (int Column = 0; Column <= FromCopyIndex; Column++)
            {
                Scratch[Column] = ToMul * FromCopy.GetD(Column);
            }

            // Add these up with a carry.
            Result.SetD(0, Scratch[0] & 0xFFFFFFFF);
            ulong Carry = Scratch[0] >> 32;

            for (int Column = 1; Column <= FromCopyIndex; Column++)
            {
                ulong Total = Scratch[Column] + Carry;
                Result.SetD(Column, Total & 0xFFFFFFFF);
                Carry = Total >> 32;
            }

            if (Carry != 0)
            {
                Result.IncrementIndex(); // This might throw an exception if it overflows.
                Result.SetD(FromCopyIndex + 1, Carry);
            }

            return(Result.GetIndex());
        }
Esempio n. 4
0
        // This is another optimization.  This is used
        // when the top digit is 1 and all of the other
        // digits are zero.  This is effectively just a
        // shift-left operation.
        internal void MultiplyTopOne(Integer Result, Integer ToMul)
        {
            // try
            // {
            int TotalIndex = Result.GetIndex() + ToMul.GetIndex();

            if (TotalIndex >= Integer.DigitArraySize)
            {
                throw(new Exception("MultiplyTopOne() overflow."));
            }

            int ToMulIndex  = ToMul.GetIndex();
            int ResultIndex = Result.GetIndex();

            for (int Column = 0; Column <= ToMulIndex; Column++)
            {
                Result.SetD(Column + ResultIndex, ToMul.GetD(Column));
            }

            for (int Column = 0; Column < ResultIndex; Column++)
            {
                Result.SetD(Column, 0);
            }

            // No Carrys need to be done.
            Result.SetIndex(TotalIndex);

            /*
             * }
             * catch( Exception ) // Except )
             * {
             * // "Exception in MultiplyTopOne: " + Except.Message
             * }
             */
        }
Esempio n. 5
0
        private bool ShortDivide(Integer ToDivide,
                                 Integer DivideBy,
                                 Integer Quotient,
                                 Integer Remainder)
        {
            Quotient.Copy(ToDivide);
            // DivideBy has an Index of zero:
            ulong DivideByU  = DivideBy.GetD(0);
            ulong RemainderU = 0;

            // Get the first one set up.
            if (DivideByU > Quotient.GetD(Quotient.GetIndex()))
            {
                Quotient.SetD(Quotient.GetIndex(), 0);
            }
            else
            {
                ulong OneDigit = Quotient.GetD(Quotient.GetIndex());
                Quotient.SetD(Quotient.GetIndex(), OneDigit / DivideByU);
                RemainderU = OneDigit % DivideByU;
                ToDivide.SetD(ToDivide.GetIndex(), RemainderU);
            }

            // Now do the rest.
            for (int Count = Quotient.GetIndex(); Count >= 1; Count--)
            {
                ulong TwoDigits = ToDivide.GetD(Count);
                TwoDigits <<= 32;
                TwoDigits  |= ToDivide.GetD(Count - 1);
                Quotient.SetD(Count - 1, TwoDigits / DivideByU);
                RemainderU = TwoDigits % DivideByU;
                ToDivide.SetD(Count, 0);
                ToDivide.SetD(Count - 1, RemainderU); // What's left to divide.
            }

            // Set the index for the quotient.
            // The quotient would have to be at least 1 here,
            // so it will find where to set the index.
            for (int Count = Quotient.GetIndex(); Count >= 0; Count--)
            {
                if (Quotient.GetD(Count) != 0)
                {
                    Quotient.SetIndex(Count);
                    break;
                }
            }

            Remainder.SetD(0, RemainderU);
            Remainder.SetIndex(0);
            if (RemainderU == 0)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Esempio n. 6
0
        // This is a variation on ShortDivide that returns
        // the remainder.
        // Also, DivideBy is a ulong.
        internal ulong ShortDivideRem(Integer ToDivideOriginal,
                                      ulong DivideByU,
                                      Integer Quotient)
        {
            if (ToDivideOriginal.IsULong())
            {
                ulong ToDiv = ToDivideOriginal.GetAsULong();
                ulong Q     = ToDiv / DivideByU;
                Quotient.SetFromULong(Q);
                return(ToDiv % DivideByU);
            }

            ToDivide.Copy(ToDivideOriginal);
            Quotient.Copy(ToDivide);
            ulong RemainderU = 0;

            if (DivideByU > Quotient.GetD(Quotient.GetIndex()))
            {
                Quotient.SetD(Quotient.GetIndex(), 0);
            }
            else
            {
                ulong OneDigit = Quotient.GetD(Quotient.GetIndex());
                Quotient.SetD(Quotient.GetIndex(), OneDigit / DivideByU);
                RemainderU = OneDigit % DivideByU;
                ToDivide.SetD(ToDivide.GetIndex(), RemainderU);
            }

            for (int Count = Quotient.GetIndex(); Count >= 1; Count--)
            {
                ulong TwoDigits = ToDivide.GetD(Count);
                TwoDigits <<= 32;
                TwoDigits  |= ToDivide.GetD(Count - 1);
                Quotient.SetD(Count - 1, TwoDigits / DivideByU);
                RemainderU = TwoDigits % DivideByU;
                ToDivide.SetD(Count, 0);
                ToDivide.SetD(Count - 1, RemainderU);
            }

            for (int Count = Quotient.GetIndex(); Count >= 0; Count--)
            {
                if (Quotient.GetD(Count) != 0)
                {
                    Quotient.SetIndex(Count);
                    break;
                }
            }

            return(RemainderU);
        }
Esempio n. 7
0
        internal void SubtractULong(Integer Result, ulong ToSub)
        {
            if (Result.IsULong())
            {
                ulong ResultU = Result.GetAsULong();
                if (ToSub > ResultU)
                {
                    throw(new Exception("SubULong() (IsULong() and (ToSub > Result)."));
                }

                ResultU = ResultU - ToSub;
                Result.SetD(0, ResultU & 0xFFFFFFFF);
                Result.SetD(1, ResultU >> 32);
                if (Result.GetD(1) == 0)
                {
                    Result.SetIndex(0);
                }
                else
                {
                    Result.SetIndex(1);
                }

                return;
            }

            // If it got this far then Index is at least 2.
            SignedD[0] = (long)Result.GetD(0) - (long)(ToSub & 0xFFFFFFFF);
            SignedD[1] = (long)Result.GetD(1) - (long)(ToSub >> 32);
            if ((SignedD[0] >= 0) && (SignedD[1] >= 0))
            {
                // No need to reorganize it.
                Result.SetD(0, (ulong)SignedD[0]);
                Result.SetD(1, (ulong)SignedD[1]);
                return;
            }

            int Max = Result.GetIndex();

            for (int Count = 2; Count <= Max; Count++)
            {
                SignedD[Count] = (long)Result.GetD(Count);
            }

            Max = Result.GetIndex();
            for (int Count = 0; Count < Max; Count++)
            {
                if (SignedD[Count] < 0)
                {
                    SignedD[Count] += (long)0xFFFFFFFF + 1;
                    SignedD[Count + 1]--;
                }
            }

            if (SignedD[Result.GetIndex()] < 0)
            {
                throw(new Exception("SubULong() SignedD[Index] < 0."));
            }

            Max = Result.GetIndex();
            for (int Count = 0; Count <= Max; Count++)
            {
                Result.SetD(Count, (ulong)SignedD[Count]);
            }

            Max = Result.GetIndex();
            for (int Count = Max; Count >= 0; Count--)
            {
                if (Result.GetD(Count) != 0)
                {
                    Result.SetIndex(Count);
                    return;
                }
            }

            // If this was zero it wouldn't find a nonzero
            // digit to set the Index to and it would end up down here.
            Result.SetIndex(0);
        }
Esempio n. 8
0
        internal void DoSquare(Integer ToSquare)
        {
            if (ToSquare.GetIndex() == 0)
            {
                ToSquare.Square0();
                return;
            }

            if (ToSquare.GetIndex() == 1)
            {
                ToSquare.Square1();
                return;
            }

            if (ToSquare.GetIndex() == 2)
            {
                ToSquare.Square2();
                return;
            }

            // Now Index is at least 3:
            int DoubleIndex = ToSquare.GetIndex() << 1;

            if (DoubleIndex >= Integer.DigitArraySize)
            {
                throw(new Exception("Square() overflowed."));
            }

            for (int Row = 0; Row <= ToSquare.GetIndex(); Row++)
            {
                if (ToSquare.GetD(Row) == 0)
                {
                    for (int Column = 0; Column <= ToSquare.GetIndex(); Column++)
                    {
                        M[Column + Row, Row] = 0;
                    }
                }
                else
                {
                    for (int Column = 0; Column <= ToSquare.GetIndex(); Column++)
                    {
                        M[Column + Row, Row] = ToSquare.GetD(Row) * ToSquare.GetD(Column);
                    }
                }
            }

            // Add the columns up with a carry.
            ToSquare.SetD(0, M[0, 0] & 0xFFFFFFFF);
            ulong Carry = M[0, 0] >> 32;

            for (int Column = 1; Column <= DoubleIndex; Column++)
            {
                ulong TotalLeft  = 0;
                ulong TotalRight = 0;
                for (int Row = 0; Row <= Column; Row++)
                {
                    if (Row > ToSquare.GetIndex())
                    {
                        break;
                    }

                    if (Column > (ToSquare.GetIndex() + Row))
                    {
                        continue;
                    }

                    TotalRight += M[Column, Row] & 0xFFFFFFFF;
                    TotalLeft  += M[Column, Row] >> 32;
                }

                TotalRight += Carry;
                ToSquare.SetD(Column, TotalRight & 0xFFFFFFFF);
                Carry  = TotalRight >> 32;
                Carry += TotalLeft;
            }

            ToSquare.SetIndex(DoubleIndex);
            if (Carry != 0)
            {
                ToSquare.SetIndex(ToSquare.GetIndex() + 1);
                if (ToSquare.GetIndex() >= Integer.DigitArraySize)
                {
                    throw(new Exception("Square() overflow."));
                }

                ToSquare.SetD(ToSquare.GetIndex(), Carry);
            }
        }
Esempio n. 9
0
        internal void Multiply(Integer Result, Integer ToMul)
        {
            // try
            // {
            if (Result.IsZero())
            {
                return;
            }

            if (ToMul.IsULong())
            {
                MultiplyULong(Result, ToMul.GetAsULong());
                SetMultiplySign(Result, ToMul);
                return;
            }

            // It could never get here if ToMul is zero because GetIsULong()
            // would be true for zero.
            // if( ToMul.IsZero())
            int TotalIndex = Result.GetIndex() + ToMul.GetIndex();

            if (TotalIndex >= Integer.DigitArraySize)
            {
                throw(new Exception("Multiply() overflow."));
            }

            int CountTo = ToMul.GetIndex();

            for (int Row = 0; Row <= CountTo; Row++)
            {
                if (ToMul.GetD(Row) == 0)
                {
                    int CountZeros = Result.GetIndex();
                    for (int Column = 0; Column <= CountZeros; Column++)
                    {
                        M[Column + Row, Row] = 0;
                    }
                }
                else
                {
                    int CountMult = Result.GetIndex();
                    for (int Column = 0; Column <= CountMult; Column++)
                    {
                        M[Column + Row, Row] = ToMul.GetD(Row) * Result.GetD(Column);
                    }
                }
            }

            // Add the columns up with a carry.
            Result.SetD(0, M[0, 0] & 0xFFFFFFFF);
            ulong Carry       = M[0, 0] >> 32;
            int   ResultIndex = Result.GetIndex();
            int   MulIndex    = ToMul.GetIndex();

            for (int Column = 1; Column <= TotalIndex; Column++)
            {
                ulong TotalLeft  = 0;
                ulong TotalRight = 0;
                for (int Row = 0; Row <= MulIndex; Row++)
                {
                    if (Row > Column)
                    {
                        break;
                    }

                    if (Column > (ResultIndex + Row))
                    {
                        continue;
                    }

                    // Split the ulongs into right and left sides
                    // so that they don't overflow.
                    TotalRight += M[Column, Row] & 0xFFFFFFFF;
                    TotalLeft  += M[Column, Row] >> 32;
                }

                TotalRight += Carry;
                Result.SetD(Column, TotalRight & 0xFFFFFFFF);
                Carry  = TotalRight >> 32;
                Carry += TotalLeft;
            }

            Result.SetIndex(TotalIndex);
            if (Carry != 0)
            {
                Result.IncrementIndex(); // This can throw an exception if it overflowed the index.
                Result.SetD(Result.GetIndex(), Carry);
            }

            SetMultiplySign(Result, ToMul);
        }