java生成pi到第n位数字

发布于 2024-12-19 12:13:11 字数 533 浏览 2 评论 0原文

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

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

简而言之,无论哪种方式,我都需要提高 BigDecimal 取决于第 n 位数字是什么。我如何将 BigDecimal 的精度提高到第 n 位?另外,如果有更好更快的方法,请您指出正确的方向。

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

I wanted to know how I can generate pi to the nth digit. I have a couple of basic ideas.

  1. Use Math.PI and increase the precision (if that's possible)
  2. Use Euler's formula to generate pi but even here, I would need to increase the precision (I think)
    Euler's formula for PI
  3. There is also Srinivasa Ramanujan's formula for generating PI which is known for it's rapid convergence. This formula seems difficult to implement. I believe, I would have to also increase deicmal precision here.
    enter image description here

So in short, either way, I would need to increase the precision of BigDecimal depending on what the nth digit is. How would I go about increasing the precision of BigDecimal to nth digit? Also, if there is a better and faster of doing this, can you please point me in the correct direction.

EDIT: I just want to generate PI. I don't want to use for calculations. and this is a question about how I can use BigDecimal to implement my ideas of generating PI.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

森罗 2024-12-26 12:13:11
  • Math.PI 的类型为 double。这意味着大约 15 位十进制数字的精度,这就是您拥有的全部数据;没有什么可以神奇地使 PI 的附加数字出现。
  • BigDecimal 具有任意精度。 setScale() 允许您创建具有任意精度的 BigDecimal 对象,并且大多数算术方法会根据需要自动增加精度,但当然精度越高,所有计算都会越慢。
  • 具有讽刺意味的是,实现拉马努金公式最困难的部分是常数因子中的 sqrt(2),因为 BigDecimal 没有内置 sqrt(),因此您必须编写自己的 sqrt() 。
  • Math.PI is of type double. That means about 15 decimal digits of precision, and that is all the data you have; nothing will magically make additional digits of PI appear.
  • BigDecimal has arbitrary precision. setScale() allows you to create BigDecimal objects with as much precision as you want and most of the arithmetic methods will automatically increase precision as required, but of course the more precision, the slower all calculations will be.
  • The most difficult part of implementing Ramanujan's formula will ironically be the sqrt(2) in the constant factor, because there is not built-in sqrt() for BigDecimal, so you'll have to write your own.
最终幸福 2024-12-26 12:13:11

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

,例如,

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

重要的是您在计算中使用的所有 BigDecimal 都使用该 >MathContext
Heron 的方法应该只需 10 次迭代即可为您提供 1000 位数字的精度,并且只需 20 次迭代即可为您提供 100 万位数字的精度,因此它当然已经足够好了。
另外,在程序开始时仅创建一次所有常量BigDecimal,例如26390

You need to use MathContext to increase the precision of the BigDecimal

e.g.

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

It's important that ALL the BigDecimals you use in your calculations use that MathContext.
Heron's method should give you 1000 digits precision with only 10 iterations and a million digits with 20 iterations so it's certainly good enough.
Also, create all the constant BigDecimals like e.g. 26390 only once at the start of your program.

殊姿 2024-12-26 12:13:11

您可以使用此代码

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;
}
}

资源

You can use this code

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文