internal static BigInteger pow2ModPow(BigInteger _base, BigInteger exponent, int j) { // PRE: (base > 0), (exponent > 0) and (j > 0) BigInteger res = BigInteger.ONE; BigInteger e = exponent.copy(); BigInteger baseMod2toN = _base.copy(); BigInteger res2; /* * If 'base' is odd then it's coprime with 2^j and phi(2^j) = 2^(j-1); * so we can reduce reduce the exponent (mod 2^(j-1)). */ if (_base.testBit(0)) { inplaceModPow2(e, j - 1); } inplaceModPow2(baseMod2toN, j); for (int i = e.bitLength() - 1; i >= 0; i--) { res2 = res.copy(); inplaceModPow2(res2, j); res = res.multiply(res2); if (BitLevel.testBit(e, i)) { res = res.multiply(baseMod2toN); inplaceModPow2(res, j); } } inplaceModPow2(res, j); return(res); }
public static BigInteger pow(BigInteger _base, int exponent) { // PRE: exp > 0 BigInteger res = BigInteger.ONE; BigInteger acc = _base; for (; exponent > 1; exponent >>= 1) { if ((exponent & 1) != 0) { // if odd, multiply one more time by acc res = res.multiply(acc); } // acc = base^(2^i) //a limit where karatsuba performs a faster square than the square algorithm if (acc.numberLength == 1) { acc = acc.multiply(acc); // square } else { acc = new BigInteger(1, square(acc.digits, acc.numberLength, new int [acc.numberLength << 1])); } } // exponent == 1, multiply one more time res = res.multiply(acc); return(res); }
public static BigInteger powerOf10(long exp) { // PRE: exp >= 0 int intExp = (int)exp; // "SMALL POWERS" if (exp < bigTenPows.Length) { // The largest power that fit in 'long' type return(bigTenPows[intExp]); } else if (exp <= 50) { // To calculate: 10^exp return(BigInteger.TEN.pow(intExp)); } else if (exp <= 1000) { // To calculate: 5^exp * 2^exp return(bigFivePows[1].pow(intExp).shiftLeft(intExp)); } if (exp <= Int32.MaxValue) { // To calculate: 5^exp * 2^exp return(bigFivePows[1].pow(intExp).shiftLeft(intExp)); } /* * "HUGE POWERS" * * This branch probably won't be executed since the power of ten is too * big. */ // To calculate: 5^exp BigInteger powerOfFive = bigFivePows[1].pow(Int32.MaxValue); BigInteger res = powerOfFive; long longExp = exp - Int32.MaxValue; intExp = (int)(exp % Int32.MaxValue); while (longExp > Int32.MaxValue) { res = res.multiply(powerOfFive); longExp -= Int32.MaxValue; } res = res.multiply(bigFivePows[1].pow(intExp)); // To calculate: 5^exp << exp res = res.shiftLeft(Int32.MaxValue); longExp = exp - Int32.MaxValue; while (longExp > Int32.MaxValue) { res = res.shiftLeft(Int32.MaxValue); longExp -= Int32.MaxValue; } res = res.shiftLeft(intExp); return(res); }
public static BigInteger multiplyByFivePow(BigInteger val, int exp) { // PRE: exp >= 0 if (exp < fivePows.Length) { return(multiplyByPositiveInt(val, fivePows[exp])); } else if (exp < bigFivePows.Length) { return(val.multiply(bigFivePows[exp])); } else // Large powers of five { return(val.multiply(bigFivePows[1].pow(exp))); } }
public static BigInteger multiplyByTenPow(BigInteger val, long exp) { // PRE: exp >= 0 return((exp < tenPows.Length) ? multiplyByPositiveInt(val, tenPows[(int)exp]) : val.multiply(powerOf10(exp))); }
internal static BigInteger evenModPow(BigInteger _base, BigInteger exponent, BigInteger modulus) { // PRE: (base > 0), (exponent > 0), (modulus > 0) and (modulus even) // STEP 1: Obtain the factorization 'modulus'= q * 2^j. int j = modulus.getLowestSetBit(); BigInteger q = modulus.shiftRight(j); // STEP 2: Compute x1 := base^exponent (mod q). BigInteger x1 = oddModPow(_base, exponent, q); // STEP 3: Compute x2 := base^exponent (mod 2^j). BigInteger x2 = pow2ModPow(_base, exponent, j); // STEP 4: Compute q^(-1) (mod 2^j) and y := (x2-x1) * q^(-1) (mod 2^j) BigInteger qInv = modPow2Inverse(q, j); BigInteger y = (x2.subtract(x1)).multiply(qInv); inplaceModPow2(y, j); if (y.sign < 0) { y = y.add(BigInteger.getPowerOfTwo(j)); } // STEP 5: Compute and return: x1 + q * y return(x1.add(q.multiply(y))); }
internal static BigInteger modPow2Inverse(BigInteger x, int n) { // PRE: (x > 0), (x is odd), and (n > 0) BigInteger y = new BigInteger(1, new int[1 << n]); y.numberLength = 1; y.digits[0] = 1; y.sign = 1; for (int i = 1; i < n; i++) { if (BitLevel.testBit(x.multiply(y), i)) { // Adding 2^i to y (setting the i-th bit) y.digits[i >> 5] |= (1 << (i & 31)); } } return(y); }
internal static BigInteger modPow2Inverse(BigInteger x, int n) { // PRE: (x > 0), (x is odd), and (n > 0) BigInteger y = new BigInteger(1, new int[1 << n]); y.numberLength = 1; y.digits[0] = 1; y.sign = 1; for (int i = 1; i < n; i++) { if (BitLevel.testBit(x.multiply(y), i)) { // Adding 2^i to y (setting the i-th bit) y.digits[i >> 5] |= (1 << (i & 31)); } } return y; }
public static BigInteger multiplyByFivePow(BigInteger val, int exp) { // PRE: exp >= 0 if (exp < fivePows.Length) { return multiplyByPositiveInt(val, fivePows[exp]); } else if (exp < bigFivePows.Length) { return val.multiply(bigFivePows[exp]); } else {// Large powers of five return val.multiply(bigFivePows[1].pow(exp)); } }
public static BigInteger multiplyByTenPow(BigInteger val, long exp) { // PRE: exp >= 0 return ((exp < tenPows.Length) ? multiplyByPositiveInt(val, tenPows[(int)exp]) : val.multiply(powerOf10(exp))); }