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); }
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())); }
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); }
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()); }
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); }
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)); }