Merge pull request #731 from DDullahan/Development

Added FastPower
This commit is contained in:
Libin Yang 2019-05-10 15:34:11 +08:00 committed by GitHub
commit 64bd1a147e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 69 additions and 0 deletions

View File

@ -0,0 +1,37 @@
package src.main.java.com.Others;
import java.math.BigInteger;
/**
* We may calculate power with loops, but what if the index is too large ?
* FastPower aims to calculate quickly in this circumstances with time complexity O(log k),
* where k is the index.
*
* @author DDullahan
*/
public class FastPower {
public static BigInteger calculate(BigInteger n, BigInteger k, BigInteger mod) {
BigInteger ans = BigInteger.ONE;
while (!k.equals(BigInteger.ZERO)) {
int odd = k.mod(BigInteger.valueOf(2)).compareTo(BigInteger.ZERO);
if(odd > 0){
ans = ans.multiply(n).mod(mod);
}
k = k.divide(BigInteger.valueOf(2));
n = n.multiply(n).mod(mod);
}
return ans.mod(mod);
}
public static long calculate(long n, long k, long mod) {
long ans = 1;
while (k != 0) {
if (k % 2 == 1) {
ans = (ans * n) % mod;
}
k >>= 1;
n = (n * n) % mod;
}
return ans % mod;
}
}

View File

@ -0,0 +1,32 @@
package src.main.java.com.Others;
import org.junit.*;
import java.math.BigInteger;
import static org.junit.Assert.*;
public class FastPowerTest {
void testLong(long n, long k, long m){
long result = FastPower.calculate(n,k,m);
assertEquals(result, BigInteger.valueOf(n).modPow(BigInteger.valueOf(k), BigInteger.valueOf(m)).longValue());
}
void testBigInteger(BigInteger n, BigInteger k, BigInteger m){
BigInteger result = FastPower.calculate(n,k,m);
assertEquals(result, n.modPow(k,m));
}
@Test
public void test() {
testLong(2,2,10);
testLong(100,1000,20);
testLong(123456,123456789,234);
testBigInteger(BigInteger.TEN,BigInteger.TEN, BigInteger.valueOf(4));
testBigInteger(new BigInteger("123456"), new BigInteger("123456789"), new BigInteger("234"));
testBigInteger(new BigInteger("123456789101112"), new BigInteger("12345678910111213"), new BigInteger("567890"));
}
}