Esempio n. 1
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);
        }
Esempio n. 2
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. 3
0
        internal void MultiplyULong(Integer Result, ulong ToMul)
        {
            // Using compile-time checks, this one overflows:
            // const ulong Test = ((ulong)0xFFFFFFFF + 1) * ((ulong)0xFFFFFFFF + 1);
            // This one doesn't:
            // const ulong Test = (ulong)0xFFFFFFFF * ((ulong)0xFFFFFFFF + 1);
            if (Result.IsZero())
            {
                return; // Then the answer is zero, which it already is.
            }
            if (ToMul == 0)
            {
                Result.SetToZero();
                return;
            }

            ulong B0 = ToMul & 0xFFFFFFFF;
            ulong B1 = ToMul >> 32;

            if (B1 == 0)
            {
                MultiplyUInt(Result, (uint)B0);
                return;
            }

            // Since B1 is not zero:
            if ((Result.GetIndex() + 1) >= Integer.DigitArraySize)
            {
                throw(new Exception("Overflow in MultiplyULong."));
            }

            int CountTo = Result.GetIndex();

            for (int Column = 0; Column <= CountTo; Column++)
            {
                ulong Digit = Result.GetD(Column);
                M[Column, 0] = B0 * Digit;
                // Column + 1 and Row is 1, so it's just like pen and paper.
                M[Column + 1, 1] = B1 * Digit;
            }

            // Since B1 is not zero, the index is set one higher.
            Result.IncrementIndex();     // Might throw an exception if it goes out of range.
            M[Result.GetIndex(), 0] = 0; // Otherwise it would be undefined
                                         // when it's added up below.
            // Add these up with a carry.
            Result.SetD(0, M[0, 0] & 0xFFFFFFFF);
            ulong Carry = M[0, 0] >> 32;

            CountTo = Result.GetIndex();
            for (int Column = 1; Column <= CountTo; Column++)
            {
                // This does overflow:
                // const ulong Test = ((ulong)0xFFFFFFFF * (ulong)(0xFFFFFFFF))
                //                  + ((ulong)0xFFFFFFFF * (ulong)(0xFFFFFFFF));
                // Split the ulongs into right and left sides
                // so that they don't overflow.
                ulong TotalLeft  = 0;
                ulong TotalRight = 0;
                // There's only the two rows for this.
                for (int Row = 0; Row <= 1; Row++)
                {
                    ulong MValue = M[Column, Row];
                    TotalRight += MValue & 0xFFFFFFFF;
                    TotalLeft  += MValue >> 32;
                }

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

            if (Carry != 0)
            {
                Result.IncrementIndex(); // This can throw an exception.
                Result.SetD(Result.GetIndex(), Carry);
            }
        }