public void Multiply(Natural factor1, Natural factor2, out Natural product)
        {
            if (factor1 == Natural.Zero || factor2 == Natural.Zero)
            {
                product = Natural.Zero;
            }
            else if (factor1 == Natural.One)
            {
                product = factor2.Clone();
            }
            else
            {
                Natural counter = factor2.Clone();
                product = factor1.Clone();

                product.PushLength(factor1.usedDigits * factor2.usedDigits);

                while (counter > 1) // We already have 1 factor1
                {
                    Natural.Add(product, factor1);
                    Natural.Decrement(counter);
                }

                product.PopLength();
            }
        }
예제 #2
0
        public void Multiply(Natural factor1, Natural factor2, out Natural product)
        {
            if (factor1 == 0 || factor2 == 0)
            {
                product = Natural.Zero;
            }
            else if (factor2 == 1)
            {
                product = factor1.Clone();
            }
            else
            {
                product = Natural.Zero;

                for (int i = 0; i < factor1.usedDigits; i++)
                {
                    Digit d = factor1.digits[i];

                    Natural partial = MulDigit(factor2, d);
                    Natural.ShiftLeft(partial, i);

                    Natural.Add(product, partial);
                }
            }
        }
        public void Multiply(Natural factor1, Natural factor2)
        {
            if (factor1 == Natural.Zero || factor2 == Natural.Zero)
            {
                factor1.SetValue(Natural.Zero);
            }
            else if (factor1 == Natural.One)
            {
                factor1.SetValue(factor2);
            }
            else
            {
                Natural increase = factor1.Clone();
                Natural decrease = factor2.Clone();

                factor1.PushLength(factor1.usedDigits * factor2.usedDigits);

                while (decrease > 1) // We already have 1 factor1
                {
                    Natural.Add(factor1, increase);
                    Natural.Decrement(decrease);
                }

                factor1.PopLength();
            }
        }
예제 #4
0
            static bool LucasLehmerTest(ulong exponent, Natural mersenneNumber, ref ulong startI, ref Natural startS)//3815
            {
                Natural s = startS.Clone();

                for (ulong i = startI; i < exponent; s = ModMersenneNumber2(Square(s), (int)exponent), i++)
                {
                    ;
                }
                if (startS < mersenneNumber)
                {
                    startI++;
                    startS *= startS;
                }
                return(s == mersenneNumber - 3);
            }
        public void DivRem(Natural dividend, Natural divisor, out Natural quotient, out Natural remainder)
        {
            if (divisor == 0)
                throw new DivideByZeroException();

            dividend = dividend.Clone();

            quotient = 0;

            while (dividend >= divisor)
            {
                Natural.Subtract(dividend, divisor);
                Natural.Increment(quotient);
            }

            remainder = dividend;
        }
예제 #6
0
        private void InternalDivRem(Natural dividend, Natural divisor, out Natural quotient, out Natural remainder)
        {
            int dcmp = dividend.CompareTo(divisor);
            if (dcmp == 0)
            {
                quotient = Natural.One;
                remainder = Natural.Zero;
            }
            else if (dcmp < 0) // dividend < divisor
            {
                quotient = Natural.Zero;
                remainder = dividend.Clone(); // Do we have to clone?
            }
            else // dividend > divisor
            {
                Natural modifiedDivisor = divisor.Clone();
                Natural subquotient = Natural.One;

                long bitshifts = Natural.Log2(dividend) - Natural.Log2(modifiedDivisor); // Gets how many factors of two from divisor to dividend
                Natural.BitShiftLeft(modifiedDivisor, bitshifts); // Shifts divisor that many times (multiply by 2^bitshifts)
                Natural.BitShiftLeft(subquotient, bitshifts);

                int cmp = dividend.CompareTo(modifiedDivisor);
                if (cmp < 0) // Dividend < modifiedDivisors - shifted 1 too much
                {
                    Natural.BitShiftRight(subquotient, 1); // Divide by 2 to get the right quotient
                    Natural.BitShiftRight(modifiedDivisor, 1);
                }
                else if (cmp == 0) // Divisor equal to dividend!
                {
                    quotient = subquotient;
                    remainder = Natural.Zero;
                    return;
                }

                // dividend > modifiedDivisor
                Natural newDividend = Natural.Subtract(dividend, modifiedDivisor); // Optimize away the clone (put this in private function - clone up front)
                InternalDivRem(newDividend, divisor, out quotient, out remainder); // Repeat division on difference between dividend and modifiedDivisor

                Natural.Add(quotient, subquotient); // Add the quotient we calculated in this iteration
            }
        }
예제 #7
0
 public void Subtract(Natural minuend, Natural subtrahend, out Natural difference)
 {
     difference = minuend.Clone();
     Subtract(difference, subtrahend);
 }
예제 #8
0
 public void DivRem(Natural dividend, Natural divisor, out Natural quotient, out Natural remainder)
 {
     InternalDivRem(dividend.Clone(), divisor, out quotient, out remainder);
 }
예제 #9
0
 public void Add(Natural addend1, Natural addend2, out Natural sum)
 {
     sum = addend1.Clone();
     Add(sum, addend2);
 }
예제 #10
0
 public Integer(Natural natural)
 {
     this.natural = natural.Clone();
     Positive     = true;
 }
예제 #11
0
 public Natural Abs() => natural.Clone();