diff --git a/README.md b/README.md index 9a67cc9..47bfc24 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ | EulerNumber | 欧拉数 | [eulers-number](https://hatter.ink/static/resource/muboard/?id=eulers-number&version=latest&full=1) | | BirthdayParadox | 生日悖论 | [birthday-paradox](https://hatter.ink/static/resource/muboard/?id=birthday-paradox&version=latest&full=1) | | ChudnovskyAlgorithm | 楚德诺夫斯基算法 | [chudnovsky-algorithm](https://hatter.ink/static/resource/muboard/?id=chudnovsky-algorithm&version=latest&full=1) | +| BinaryExponentiation | 快速幂 | [binary-exponentiation](https://hatter.ink/static/resource/muboard/?id=binary-exponentiation&version=1) |
diff --git a/src/main/java/me/hatter/math/BinaryExponentiation.java b/src/main/java/me/hatter/math/BinaryExponentiation.java new file mode 100644 index 0000000..9c0c690 --- /dev/null +++ b/src/main/java/me/hatter/math/BinaryExponentiation.java @@ -0,0 +1,35 @@ +package me.hatter.math; + +import java.math.BigInteger; +import java.util.Arrays; + +// https://oi-wiki.org/math/binary-exponentiation/ +public class BinaryExponentiation { + + public static void main(String[] args) { + System.out.println(binPow(BigInteger.valueOf(2), BigInteger.valueOf(100))); + + for (int i = 0; i < 100; i++) { + for (int j = 0; j < 100; j++) { + BigInteger a = BigInteger.valueOf(i).pow(j); + BigInteger b = binPow(BigInteger.valueOf(i), BigInteger.valueOf(j)); + + if (a.compareTo(b) != 0) { + System.out.println(Arrays.asList(i, j, a, b)); + } + } + } + } + + public static BigInteger binPow(BigInteger a, BigInteger b) { + BigInteger result = BigInteger.ONE; + while (b.compareTo(BigInteger.ZERO) > 0) { + if (b.mod(BigInteger.valueOf(2)).compareTo(BigInteger.ONE) == 0) { + result = result.multiply(a); + } + a = a.multiply(a); + b = b.divide(BigInteger.valueOf(2)); + } + return result; + } +} diff --git a/src/main/java/me/hatter/math/util/MathUtil.java b/src/main/java/me/hatter/math/util/MathUtil.java index 4e5b692..1bf94e2 100644 --- a/src/main/java/me/hatter/math/util/MathUtil.java +++ b/src/main/java/me/hatter/math/util/MathUtil.java @@ -46,6 +46,14 @@ public class MathUtil { return v.add(BigDecimal.valueOf(nums[0])); } + public static BigInteger max(BigInteger a, BigInteger b) { + return (a.compareTo(b) < 0) ? b : a; + } + + public static BigInteger min(BigInteger a, BigInteger b) { + return (a.compareTo(b) < 0) ? a : b; + } + // https://oi-wiki.org/math/number-theory/gcd/ public static BigInteger gcd(BigInteger a, BigInteger b) { while (b.compareTo(BigInteger.ZERO) != 0) { diff --git a/src/test/java/me/hatter/math/util/MathUtilTest.java b/src/test/java/me/hatter/math/util/MathUtilTest.java index 44fe142..bc94d3a 100644 --- a/src/test/java/me/hatter/math/util/MathUtilTest.java +++ b/src/test/java/me/hatter/math/util/MathUtilTest.java @@ -48,6 +48,16 @@ public class MathUtilTest { )); } + @Test + public void testMinMax() { + Assert.assertEquals(BigInteger.valueOf(10), MathUtil.max(BigInteger.valueOf(1), BigInteger.valueOf(10))); + Assert.assertEquals(BigInteger.valueOf(10), MathUtil.max(BigInteger.valueOf(10), BigInteger.valueOf(9))); + Assert.assertEquals(BigInteger.valueOf(10), MathUtil.max(BigInteger.valueOf(10), BigInteger.valueOf(10))); + Assert.assertEquals(BigInteger.valueOf(10), MathUtil.min(BigInteger.valueOf(10), BigInteger.valueOf(10))); + Assert.assertEquals(BigInteger.valueOf(1), MathUtil.min(BigInteger.valueOf(1), BigInteger.valueOf(10))); + Assert.assertEquals(BigInteger.valueOf(9), MathUtil.min(BigInteger.valueOf(10), BigInteger.valueOf(9))); + } + @Test public void testSqrt() { Assert.assertEquals(