diff --git a/src/main/java/com/Others/FastPower.java b/src/main/java/com/Others/FastPower.java new file mode 100644 index 00000000..8cc1b8b6 --- /dev/null +++ b/src/main/java/com/Others/FastPower.java @@ -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; + } +} diff --git a/src/main/java/com/Others/FastPowerTest.java b/src/main/java/com/Others/FastPowerTest.java new file mode 100644 index 00000000..bd61704b --- /dev/null +++ b/src/main/java/com/Others/FastPowerTest.java @@ -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")); + + } +} \ No newline at end of file