Ejemplo n.º 1
0
        public BigInteger modPow(BigInteger exponent, BigInteger m)
        {
            if (m.sign <= 0)
            {
                throw new ArithmeticException("BigInteger: modulus not positive");
            }
            BigInteger _base = this;

            if (m.isOne() | (exponent.sign > 0 & _base.sign == 0))
            {
                return(BigInteger.ZERO);
            }
            if (_base.sign == 0 && exponent.sign == 0)
            {
                return(BigInteger.ONE);
            }
            if (exponent.sign < 0)
            {
                _base    = modInverse(m);
                exponent = exponent.negate();
            }
            // From now on: (m > 0) and (exponent >= 0)
            BigInteger res = (m.testBit(0)) ? Division.oddModPow(_base.abs(),
                                                                 exponent, m) : Division.evenModPow(_base.abs(), exponent, m);

            if ((_base.sign < 0) && exponent.testBit(0))
            {
                // -b^e mod m == ((-1 mod m) * (b^e mod m)) mod m
                res = m.subtract(BigInteger.ONE).multiply(res).mod(m);
            }
            // else exponent is even, so base^exp is positive
            return(res);
        }
Ejemplo n.º 2
0
        public BigInteger gcd(BigInteger val)
        {
            BigInteger val1 = this.abs();
            BigInteger val2 = val.abs();

            // To avoid a possible division by zero
            if (val1.signum() == 0)
            {
                return(val2);
            }
            else if (val2.signum() == 0)
            {
                return(val1);
            }

            // Optimization for small operands
            // (op2.bitLength() < 64) and (op1.bitLength() < 64)
            if (((val1.numberLength == 1) || ((val1.numberLength == 2) && (val1.digits[1] > 0))) &&
                (val2.numberLength == 1 || (val2.numberLength == 2 && val2.digits[1] > 0)))
            {
                return(BigInteger.valueOf(Division.gcdBinary(val1.longValue(), val2
                                                             .longValue())));
            }

            return(Division.gcdBinary(val1.copy(), val2.copy()));
        }
Ejemplo n.º 3
0
        internal static String bigInteger2String(BigInteger val, int radix)
        {
            int sign = val.sign;
            int numberLength = val.numberLength;
            int[] digits = val.digits;

            if (sign == 0) {
                return "0"; //$NON-NLS-1$
            }
            if (numberLength == 1) {
                int highDigit = digits[numberLength - 1];
                long v = highDigit & 0xFFFFFFFFL;
                if (sign < 0) {
                    v = -v;
                }
                return Convert.ToString(v, radix);
            }
            if ((radix == 10) || (radix < 0)
                || (radix > 26)) {
                return val.ToString();
            }
            double bitsForRadixDigit;
            bitsForRadixDigit = Math.Log(radix) / Math.Log(2);
            int resLengthInChars = (int) (val.abs().bitLength() / bitsForRadixDigit + ((sign < 0) ? 1
                                                                                       : 0)) + 1;

            char[] result = new char[resLengthInChars];
            int currentChar = resLengthInChars;
            int resDigit;
            if (radix != 16) {
                int[] temp = new int[numberLength];
                Array.Copy(digits, 0, temp, 0, numberLength);
                int tempLen = numberLength;
                int charsPerInt = digitFitInInt[radix];
                int i;
                // get the maximal power of radix that fits in int
                int bigRadix = bigRadices[radix - 2];
                while (true) {
                    // divide the array of digits by bigRadix and convert remainders
                    // to characters collecting them in the char array
                    resDigit = Division.divideArrayByInt(temp, temp, tempLen,
                                                         bigRadix);
                    int previous = currentChar;
                    do {
                        result[--currentChar] = Convert.ToString(resDigit % radix, radix)[0];
                    } while (((resDigit /= radix) != 0) && (currentChar != 0));
                    int delta = charsPerInt - previous + currentChar;
                    for (i = 0; i < delta && currentChar > 0; i++) {
                        result[--currentChar] = '0';
                    }
                    for (i = tempLen - 1; (i > 0) && (temp[i] == 0); i--) {
                        ;
                    }
                    tempLen = i + 1;
                    if ((tempLen == 1) && (temp[0] == 0)) { // the quotient is 0
                        break;
                    }
                }
            } else {
                // radix == 16
                for (int i = 0; i < numberLength; i++) {
                    for (int j = 0; (j < 8) && (currentChar > 0); j++) {
                        resDigit = digits[i] >> (j << 2) & 0xf;
                        result[--currentChar] = Convert.ToString(resDigit % radix, 16)[0];
                    }
                }
            }
            while (result[currentChar] == '0') {
                currentChar++;
            }
            if (sign == -1) {
                result[--currentChar] = '-';
            }
            return new String(result, currentChar, resLengthInChars - currentChar);
        }
Ejemplo n.º 4
0
        public BigInteger gcd(BigInteger val)
        {
            BigInteger val1 = this.abs();
            BigInteger val2 = val.abs();
            // To avoid a possible division by zero
            if (val1.signum() == 0) {
                return val2;
            } else if (val2.signum() == 0) {
                return val1;
            }

            // Optimization for small operands
            // (op2.bitLength() < 64) and (op1.bitLength() < 64)
            if (((val1.numberLength == 1) || ((val1.numberLength == 2) && (val1.digits[1] > 0)))
                && (val2.numberLength == 1 || (val2.numberLength == 2 && val2.digits[1] > 0))) {
                return BigInteger.valueOf(Division.gcdBinary(val1.longValue(), val2
                                                             .longValue()));
            }

            return Division.gcdBinary(val1.copy(), val2.copy());
        }
Ejemplo n.º 5
0
        private static BigDecimal divideBigIntegers(BigInteger scaledDividend, BigInteger scaledDivisor, int scale, RoundingMode roundingMode)
        {
            BigInteger[] quotAndRem = scaledDividend.divideAndRemainder(scaledDivisor);  // quotient and remainder

            // If after division there is a remainder...
            BigInteger quotient = quotAndRem[0];
            BigInteger remainder = quotAndRem[1];
            if (remainder.signum() == 0) {
                return new BigDecimal(quotient, scale);
            }
            int sign = scaledDividend.signum() * scaledDivisor.signum();
            int compRem;                                      // 'compare to remainder'
            if(scaledDivisor.bitLength() < 63) { // 63 in order to avoid out of long after <<1
                long rem = remainder.longValue();
                long divisor = scaledDivisor.longValue();
                compRem = longCompareTo(Math.Abs(rem) << 1,Math.Abs(divisor));
                // To look if there is a carry
                compRem = roundingBehavior(quotient.testBit(0) ? 1 : 0,
                                           sign * (5 + compRem), roundingMode);

            } else {
                // Checking if:  remainder * 2 >= scaledDivisor
                compRem = remainder.abs().shiftLeftOneBit().compareTo(scaledDivisor.abs());
                compRem = roundingBehavior(quotient.testBit(0) ? 1 : 0,
                                           sign * (5 + compRem), roundingMode);
            }
            if (compRem != 0) {
                if(quotient.bitLength() < 63) {
                    return valueOf(quotient.longValue() + compRem,scale);
                }
                quotient = quotient.add(BigInteger.valueOf(compRem));
                return new BigDecimal(quotient, scale);
            }
            // Constructing the result with the appropriate unscaled value
            return new BigDecimal(quotient, scale);
        }
Ejemplo n.º 6
0
        internal static String bigInteger2String(BigInteger val, int radix)
        {
            int sign         = val.sign;
            int numberLength = val.numberLength;

            int[] digits = val.digits;

            if (sign == 0)
            {
                return("0"); //$NON-NLS-1$
            }
            if (numberLength == 1)
            {
                int  highDigit = digits[numberLength - 1];
                long v         = highDigit & 0xFFFFFFFFL;
                if (sign < 0)
                {
                    v = -v;
                }
                return(Convert.ToString(v, radix));
            }
            if ((radix == 10) || (radix < 0) ||
                (radix > 26))
            {
                return(val.ToString());
            }
            double bitsForRadixDigit;

            bitsForRadixDigit = Math.Log(radix) / Math.Log(2);
            int resLengthInChars = (int)(val.abs().bitLength() / bitsForRadixDigit + ((sign < 0) ? 1
                                                                                       : 0)) + 1;

            char[] result      = new char[resLengthInChars];
            int    currentChar = resLengthInChars;
            int    resDigit;

            if (radix != 16)
            {
                int[] temp = new int[numberLength];
                Array.Copy(digits, 0, temp, 0, numberLength);
                int tempLen     = numberLength;
                int charsPerInt = digitFitInInt[radix];
                int i;
                // get the maximal power of radix that fits in int
                int bigRadix = bigRadices[radix - 2];
                while (true)
                {
                    // divide the array of digits by bigRadix and convert remainders
                    // to characters collecting them in the char array
                    resDigit = Division.divideArrayByInt(temp, temp, tempLen,
                                                         bigRadix);
                    int previous = currentChar;
                    do
                    {
                        result[--currentChar] = Convert.ToString(resDigit % radix, radix)[0];
                    } while (((resDigit /= radix) != 0) && (currentChar != 0));
                    int delta = charsPerInt - previous + currentChar;
                    for (i = 0; i < delta && currentChar > 0; i++)
                    {
                        result[--currentChar] = '0';
                    }
                    for (i = tempLen - 1; (i > 0) && (temp[i] == 0); i--)
                    {
                        ;
                    }
                    tempLen = i + 1;
                    if ((tempLen == 1) && (temp[0] == 0))   // the quotient is 0
                    {
                        break;
                    }
                }
            }
            else
            {
                // radix == 16
                for (int i = 0; i < numberLength; i++)
                {
                    for (int j = 0; (j < 8) && (currentChar > 0); j++)
                    {
                        resDigit = digits[i] >> (j << 2) & 0xf;
                        result[--currentChar] = Convert.ToString(resDigit % radix, 16)[0];
                    }
                }
            }
            while (result[currentChar] == '0')
            {
                currentChar++;
            }
            if (sign == -1)
            {
                result[--currentChar] = '-';
            }
            return(new String(result, currentChar, resLengthInChars - currentChar));
        }