Esempio n. 1
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. 2
0
        internal void MultiplyUInt(Integer Result, ulong ToMul)
        {
            try
            {
                if (ToMul == 0)
                {
                    Result.SetToZero();
                    return;
                }

                if (ToMul == 1)
                {
                    return;
                }

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

                // 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++)
                {
                    // Using a compile-time check on this constant,
                    // this Test value does not overflow:
                    // const ulong Test = ((ulong)0xFFFFFFFF * (ulong)(0xFFFFFFFF)) + 0xFFFFFFFF;
                    // ulong Total = checked( M[Column, 0] + Carry );
                    ulong Total = M[Column, 0] + Carry;
                    Result.SetD(Column, Total & 0xFFFFFFFF);
                    Carry = Total >> 32;
                }

                if (Carry != 0)
                {
                    Result.IncrementIndex(); // This might throw an exception if it overflows.
                    Result.SetD(Result.GetIndex(), Carry);
                }
            }
            catch (Exception Except)
            {
                throw(new Exception("Exception in MultiplyUInt(): " + Except.Message));
            }
        }
Esempio n. 3
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. 4
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);
            }
        }