From ce1f7944478bedc6e9a7074166c2ec404d04e0c1 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sat, 19 Jul 2025 20:19:12 +0800 Subject: [PATCH] feat: add math util --- .../java/me/hatter/math/util/MathUtil.java | 45 +++++++++++++++++ .../me/hatter/math/util/MathUtilTest.java | 48 +++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 src/main/java/me/hatter/math/util/MathUtil.java create mode 100644 src/test/java/me/hatter/math/util/MathUtilTest.java diff --git a/src/main/java/me/hatter/math/util/MathUtil.java b/src/main/java/me/hatter/math/util/MathUtil.java new file mode 100644 index 0000000..042bd8b --- /dev/null +++ b/src/main/java/me/hatter/math/util/MathUtil.java @@ -0,0 +1,45 @@ +package me.hatter.math.util; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.math.RoundingMode; + +public class MathUtil { + + public static final BigDecimal E = new BigDecimal( + "2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664238" + ); + + public static final BigDecimal PI = new BigDecimal( + "3.1415926535 8979323846 2643383279 5028841971 6939937510 5820974944 5923078164 0628620899 8628034825 3421170679" + .replace(" ", "")); + + public static final BigDecimal LITTLE_NUMBER = new BigDecimal( + "0.000000000000000000000000000000000000000001"); + + public static BigInteger factorial(long n) { + if (n < 0) { + throw new RuntimeException("Not supported n < 0"); + } + if (n == 0) { + return BigInteger.ONE; + } + BigInteger p = BigInteger.ONE; + for (long i = 1; i <= n; i++) { + p = p.multiply(BigInteger.valueOf(i)); + } + return p; + } + + public static boolean bigDecimalEquals(BigDecimal a, BigDecimal b) { + return a.subtract(b).abs().compareTo(LITTLE_NUMBER) < 0; + } + + public static BigDecimal simpleContinuedFraction(long[] nums) { + BigDecimal v = BigDecimal.ZERO; + for (int i = nums.length - 1; i > 0; i--) { + v = BigDecimal.ONE.divide(v.add(BigDecimal.valueOf(nums[i])), 100, RoundingMode.FLOOR); + } + return v.add(BigDecimal.valueOf(nums[0])); + } +} diff --git a/src/test/java/me/hatter/math/util/MathUtilTest.java b/src/test/java/me/hatter/math/util/MathUtilTest.java new file mode 100644 index 0000000..5bc499e --- /dev/null +++ b/src/test/java/me/hatter/math/util/MathUtilTest.java @@ -0,0 +1,48 @@ +package me.hatter.math.util; + +import org.junit.Assert; +import org.junit.Test; + +import java.math.BigDecimal; + +public class MathUtilTest { + + @Test + public void testFactorial() { + Assert.assertEquals(1, MathUtil.factorial(0).longValue()); + Assert.assertEquals(1, MathUtil.factorial(1).longValue()); + Assert.assertEquals(2, MathUtil.factorial(2).longValue()); + Assert.assertEquals(6, MathUtil.factorial(3).longValue()); + Assert.assertEquals(24, MathUtil.factorial(4).longValue()); + Assert.assertEquals(120, MathUtil.factorial(5).longValue()); + } + + @Test + public void testSimpleContinuedFraction() { + // 3.245 = [3; 4, 12, 4] + Assert.assertTrue(MathUtil.bigDecimalEquals( + new BigDecimal("3.245"), + MathUtil.simpleContinuedFraction(new long[]{3, 4, 12, 4}) + )); + // 1 = [0; 1] + Assert.assertTrue(MathUtil.bigDecimalEquals( + new BigDecimal("1"), + MathUtil.simpleContinuedFraction(new long[]{0, 1}) + )); + // 0.8 = [0; 1, 4] + Assert.assertTrue(MathUtil.bigDecimalEquals( + new BigDecimal("0.8"), + MathUtil.simpleContinuedFraction(new long[]{0, 1, 4}) + )); + // 3.14155 = [3; 7, 15, 2, 7, 1, 4, 1, 1] + Assert.assertTrue(MathUtil.bigDecimalEquals( + new BigDecimal("3.14155"), + MathUtil.simpleContinuedFraction(new long[]{3, 7, 15, 2, 7, 1, 4, 1, 1}) + )); + // 3.14165 = [3; 7, 16, 1, 3, 4, 2, 3, 1] + Assert.assertTrue(MathUtil.bigDecimalEquals( + new BigDecimal("3.14165"), + MathUtil.simpleContinuedFraction(new long[]{3, 7, 16, 1, 3, 4, 2, 3, 1}) + )); + } +}