feat: add chudnovsky algorithm

This commit is contained in:
2025-07-22 00:06:40 +08:00
parent 8c3f4d78b9
commit beac626679
3 changed files with 60 additions and 0 deletions

View File

@@ -10,6 +10,7 @@
| LeibnizFormula | $\pi$ 的莱布尼茨公式 | [leibniz-formula](https://hatter.ink/static/resource/muboard/?id=leibniz-formula&version=1) | | LeibnizFormula | $\pi$ 的莱布尼茨公式 | [leibniz-formula](https://hatter.ink/static/resource/muboard/?id=leibniz-formula&version=1) |
| EulerNumber | 欧拉数 | [eulers-number](https://hatter.ink/static/resource/muboard/?id=eulers-number&version=latest&full=1) | | 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) | | 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) |
<br> <br>

View File

@@ -0,0 +1,35 @@
package me.hatter.math;
import me.hatter.math.util.MathUtil;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
// https://zh.wikipedia.org/zh-cn/楚德诺夫斯基算法
public class ChudnovskyAlgorithm {
public static void main(String[] args) {
// 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
System.out.println(computePi());
}
public static BigDecimal computePi() {
BigDecimal c = BigDecimal.valueOf(426880).multiply(MathUtil.sqrt(BigDecimal.valueOf(10005), 100));
BigInteger m = BigInteger.valueOf(1);
BigInteger l = BigInteger.valueOf(13591409);
BigInteger x = BigInteger.valueOf(1);
BigInteger k = BigInteger.valueOf(6);
BigDecimal s = BigDecimal.valueOf(l.longValue());
for (int i = 0; i < 10; i++) {
m = (k.pow(3).subtract(k.multiply(BigInteger.valueOf(16)))).multiply(m).divide(BigInteger.valueOf(i + 1).pow(3));
l = l.add(BigInteger.valueOf(545140134));
x = x.multiply(BigInteger.valueOf(-262537412640768000L));
s = s.add(new BigDecimal(m.multiply(l)).divide(new BigDecimal(x), 100, RoundingMode.FLOOR));
k = k.add(BigInteger.valueOf(12));
}
return c.divide(s, 100, RoundingMode.FLOOR);
}
}

View File

@@ -41,4 +41,28 @@ public class MathUtil {
} }
return v.add(BigDecimal.valueOf(nums[0])); return v.add(BigDecimal.valueOf(nums[0]));
} }
// Newton-Raphson法によるBigDecimalの平方根計算
public static BigDecimal sqrt(BigDecimal n, int scale) {
if (n.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException("Cannot calculate square root of a negative number");
}
if (n.compareTo(BigDecimal.ZERO) == 0) {
return BigDecimal.ZERO;
}
BigDecimal x = n.divide(new BigDecimal("2"), scale, RoundingMode.HALF_UP);
BigDecimal precision = new BigDecimal("1").movePointLeft(scale); // 誤差の許容範囲
BigDecimal lastX;
do {
lastX = x;
x = n.divide(x, scale, RoundingMode.HALF_UP)
.add(x)
.divide(new BigDecimal("2"), scale, RoundingMode.HALF_UP);
} while (x.subtract(lastX).abs().compareTo(precision) > 0);
return x;
}
} }