9

我想知道如何将 pi 生成到第 n 位。我有几个基本的想法。

  1. 使用Math.PI并提高精度(如果可能的话)
  2. 使用欧拉公式生成 pi 但即使在这里,我也需要提高精度(我认为) PI 的欧拉公式
  3. 还有 Srinivasa Ramanujan 的 PI 生成公式,该公式以其快速收敛而闻名。这个公式似乎很难实现。我相信,我还必须在这里提高 deicmal 精度。
    在此处输入图像描述

所以简而言之,无论哪种方式,我都需要BigDecimal根据第 n 个数字来提高精度。我将如何将精度提高BigDecimal到第 n 位?另外,如果有更好更快的方法,请您指出正确的方向。

编辑:我只想生成 PI。我不想用于计算。这是一个关于如何使用 BigDecimal 来实现生成 PI 的想法的问题。

4

3 回答 3

7
  • Math.PI是类型double。这意味着大约 15 个十进制数字的精度,这就是您拥有的所有数据;没有什么能神奇地使额外的 PI 数字出现。
  • BigDecimal具有任意精度。setScale()允许您创建BigDecimal具有所需精度的对象,并且大多数算术方法会根据需要自动增加精度,但是当然精度越高,所有计算都会越慢。
  • 具有讽刺意味的是,实现 Ramanujan 公式的最困难的部分是常数因子中的 sqrt(2),因为没有内置的 sqrt() for BigDecimal,所以你必须自己编写。
于 2011-12-03T19:27:05.337 回答
4

您需要使用MathContext来提高精度BigDecimal

例如

MathContext mc = new MathContext(1000);
BigDecimal TWO = new BigDecimal(2, mc);

重要的是,BigDecimal您在计算中使用的所有 s 都使用 that MathContext。Heron 的方法应该只用 10 次迭代就可以达到 1000 位精度,而用 20 次迭代就可以达到 100 万位精度,所以它当然已经足够好了。此外,在程序开始时创建所有常量BigDecimal,例如26390只创建一次。

于 2011-12-03T21:34:18.930 回答
0

您可以使用此代码

import java.math.BigDecimal;
import java.math.RoundingMode;

public final class Pi {

private static final BigDecimal TWO = new BigDecimal("2");
private static final BigDecimal FOUR = new BigDecimal("4");
private static final BigDecimal FIVE = new BigDecimal("5");
private static final BigDecimal TWO_THIRTY_NINE = new BigDecimal("239");

private Pi() {}

public static BigDecimal pi(int numDigits) {

  int calcDigits = numDigits + 10;

  return FOUR.multiply((FOUR.multiply(arccot(FIVE, calcDigits)))
    .subtract(arccot(TWO_THIRTY_NINE, calcDigits)))
    .setScale(numDigits, RoundingMode.DOWN);
}

 private static BigDecimal arccot(BigDecimal x, int numDigits) {

BigDecimal unity = BigDecimal.ONE.setScale(numDigits,
  RoundingMode.DOWN);
BigDecimal sum = unity.divide(x, RoundingMode.DOWN);
BigDecimal xpower = new BigDecimal(sum.toString());
BigDecimal term = null;

boolean add = false;

for (BigDecimal n = new BigDecimal("3"); term == null ||
  term.compareTo(BigDecimal.ZERO) != 0; n = n.add(TWO)) {

  xpower = xpower.divide(x.pow(2), RoundingMode.DOWN);
  term = xpower.divide(n, RoundingMode.DOWN);
  sum = add ? sum.add(term) : sum.subtract(term);
  add = ! add;
}
return sum;
}
}

资源

于 2013-07-27T14:43:37.520 回答