public static BigInteger Remainder(BigInteger dividend, BigInteger divisor)
        {
            if (divisor.Sign == 0)
            {
                // math.17=BigInteger divide by zero
                throw new ArithmeticException(Messages.math17);                 //$NON-NLS-1$
            }
            int thisLen    = dividend.numberLength;
            int divisorLen = divisor.numberLength;

            if (((thisLen != divisorLen)
                                    ? ((thisLen > divisorLen) ? 1 : -1)
                                    : Elementary.CompareArrays(dividend.digits, divisor.digits, thisLen)) == BigInteger.LESS)
            {
                return(dividend);
            }
            int resLength = divisorLen;

            int[] resDigits = new int[resLength];
            if (resLength == 1)
            {
                resDigits[0] = Division.RemainderArrayByInt(dividend.digits, thisLen,
                                                            divisor.digits[0]);
            }
            else
            {
                int qLen = thisLen - divisorLen + 1;
                resDigits = Division.Divide(null, qLen, dividend.digits, thisLen,
                                            divisor.digits, divisorLen);
            }
            BigInteger result = new BigInteger(dividend.Sign, resLength, resDigits);

            result.CutOffLeadingZeroes();
            return(result);
        }
        public static BigInteger Divide(BigInteger dividend, BigInteger divisor)
        {
            if (divisor.Sign == 0)
            {
                // math.17=BigInteger divide by zero
                throw new ArithmeticException(Messages.math17);                 //$NON-NLS-1$
            }
            int divisorSign = divisor.Sign;

            if (divisor.IsOne)
            {
                return((divisor.Sign > 0) ? dividend : -dividend);
            }
            int thisSign   = dividend.Sign;
            int thisLen    = dividend.numberLength;
            int divisorLen = divisor.numberLength;

            if (thisLen + divisorLen == 2)
            {
                long val = (dividend.digits[0] & 0xFFFFFFFFL)
                           / (divisor.digits[0] & 0xFFFFFFFFL);
                if (thisSign != divisorSign)
                {
                    val = -val;
                }
                return(BigInteger.FromInt64(val));
            }
            int cmp = ((thisLen != divisorLen)
                                ? ((thisLen > divisorLen) ? 1 : -1)
                                : Elementary.CompareArrays(dividend.digits, divisor.digits, thisLen));

            if (cmp == BigInteger.EQUALS)
            {
                return((thisSign == divisorSign) ? BigInteger.One : BigInteger.MinusOne);
            }
            if (cmp == BigInteger.LESS)
            {
                return(BigInteger.Zero);
            }
            int resLength = thisLen - divisorLen + 1;

            int[] resDigits = new int[resLength];
            int   resSign   = ((thisSign == divisorSign) ? 1 : -1);

            if (divisorLen == 1)
            {
                Division.DivideArrayByInt(resDigits, dividend.digits, thisLen,
                                          divisor.digits[0]);
            }
            else
            {
                Division.Divide(resDigits, resLength, dividend.digits, thisLen,
                                divisor.digits, divisorLen);
            }
            BigInteger result = new BigInteger(resSign, resLength, resDigits);

            result.CutOffLeadingZeroes();
            return(result);
        }
        public static BigInteger DivideAndRemainder(BigInteger dividend, BigInteger divisor, out BigInteger remainder)
        {
            int divisorSign = divisor.Sign;

            if (divisorSign == 0)
            {
                // math.17=BigInteger divide by zero
                throw new ArithmeticException(Messages.math17);                 //$NON-NLS-1$
            }
            int divisorLen = divisor.numberLength;

            int[] divisorDigits = divisor.digits;
            if (divisorLen == 1)
            {
                var values = Division.DivideAndRemainderByInteger(dividend, divisorDigits[0], divisorSign);
                remainder = values[1];
                return(values[0]);
            }

            int[] thisDigits = dividend.digits;
            int   thisLen    = dividend.numberLength;
            int   cmp        = (thisLen != divisorLen)
                                ? ((thisLen > divisorLen) ? 1 : -1)
                                : Elementary.CompareArrays(thisDigits, divisorDigits, thisLen);

            if (cmp < 0)
            {
                remainder = dividend;
                return(BigInteger.Zero);
            }
            int thisSign        = dividend.Sign;
            int quotientLength  = thisLen - divisorLen + 1;
            int remainderLength = divisorLen;
            int quotientSign    = ((thisSign == divisorSign) ? 1 : -1);

            int[] quotientDigits  = new int[quotientLength];
            int[] remainderDigits = Division.Divide(quotientDigits, quotientLength,
                                                    thisDigits, thisLen, divisorDigits, divisorLen);

            var quotient = new BigInteger(quotientSign, quotientLength, quotientDigits);

            remainder = new BigInteger(thisSign, remainderLength, remainderDigits);
            quotient.CutOffLeadingZeroes();
            remainder.CutOffLeadingZeroes();

            return(quotient);
        }
Exemple #4
0
 /// <inheritdoc cref="IComparable{T}.CompareTo"/>
 public int CompareTo(BigInteger other)
 {
     if (sign > other.sign)
     {
         return(GREATER);
     }
     if (sign < other.sign)
     {
         return(LESS);
     }
     if (numberLength > other.numberLength)
     {
         return(sign);
     }
     if (numberLength < other.numberLength)
     {
         return(-other.sign);
     }
     // Equal sign and equal numberLength
     return(sign * Elementary.CompareArrays(digits, other.digits,
                                            numberLength));
 }
        /** @see BigInteger#subtract(BigInteger) */
        internal static BigInteger subtract(BigInteger op1, BigInteger op2)
        {
            int resSign;

            int[] resDigits;
            int   op1Sign = op1.Sign;
            int   op2Sign = op2.Sign;

            if (op2Sign == 0)
            {
                return(op1);
            }
            if (op1Sign == 0)
            {
                return(-op2);
            }
            int op1Len = op1.numberLength;
            int op2Len = op2.numberLength;

            if (op1Len + op2Len == 2)
            {
                long a = (op1.Digits[0] & 0xFFFFFFFFL);
                long b = (op2.Digits[0] & 0xFFFFFFFFL);
                if (op1Sign < 0)
                {
                    a = -a;
                }
                if (op2Sign < 0)
                {
                    b = -b;
                }
                return(BigInteger.FromInt64(a - b));
            }
            int cmp = ((op1Len != op2Len) ? ((op1Len > op2Len) ? 1 : -1)
                                        : Elementary.CompareArrays(op1.Digits, op2.Digits, op1Len));

            if (cmp == BigInteger.LESS)
            {
                resSign   = -op2Sign;
                resDigits = (op1Sign == op2Sign) ? subtract(op2.Digits, op2Len,
                                                            op1.Digits, op1Len) : add(op2.Digits, op2Len, op1.Digits,
                                                                                      op1Len);
            }
            else
            {
                resSign = op1Sign;
                if (op1Sign == op2Sign)
                {
                    if (cmp == BigInteger.EQUALS)
                    {
                        return(BigInteger.Zero);
                    }
                    resDigits = subtract(op1.Digits, op1Len, op2.Digits, op2Len);
                }
                else
                {
                    resDigits = add(op1.Digits, op1Len, op2.Digits, op2Len);
                }
            }
            BigInteger res = new BigInteger(resSign, resDigits.Length, resDigits);

            res.CutOffLeadingZeroes();
            return(res);
        }