生成pi到第n位java

时间:2011-12-03 19:21:26

标签: java precision bigdecimal pi

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

  1. 使用Math.PI并提高精度(如果可能的话)
  2. 使用Euler公式生成pi,但即使在这里,我也需要提高精度(我认为) Euler's formula for PI
  3. 还有Srinivasa Ramanujan用于生成PI的公式,该公式因其快速收敛而闻名。这个公式似乎很难实现。我相信,我还必须提高这里的精确度 enter image description here
  4. 简而言之,无论哪种方式,我都需要根据第n位数增加BigDecimal的精度。我如何将BigDecimal的精度提高到第n位?另外,如果有更好更快的做法,请指点我正确的方向。

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

3 个答案:

答案 0 :(得分:6)

  • Math.PI的类型为double。这意味着大约15个十进制数字的精度,这就是你拥有的所有数据;没有任何东西可以神奇地使PI的附加数字出现。
  • BigDecimal具有任意精度。 setScale()允许您创建具有所需精度的BigDecimal个对象,并且大多数算术方法将根据需要自动提高精度,但当然精度越高,所有计算都将越慢。 / LI>
  • 实现Ramanujan公式最困难的部分具有讽刺意味的是常数因子中的sqrt(2),因为BigDecimal没有内置的sqrt(),所以你必须自己编写

答案 1 :(得分:3)

您需要使用MathContext来提高BigDecimal

的精确度

e.g。

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

您在计算中使用的所有BigDecimal都使用MathContext这一点非常重要。 苍鹭的方法应该给你1000位数的精度,只有10次迭代和100位数,20次迭代,所以它当然足够好。 另外,创建所有常量BigDecimal,例如26390仅在您的计划开始时一次。

答案 2 :(得分: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;
}
}

resource