генерирование пи к n-й цифре Java - PullRequest
8 голосов
/ 03 декабря 2011

Я хотел знать, как я могу сгенерировать пи к n-й цифре. У меня есть пара основных идей.

  1. Используйте Math.PI и увеличьте точность (если это возможно)
  2. Используйте формулу Эйлера для генерации числа Пи, но даже здесь мне нужно было бы повысить точность (я думаю) Euler's formula for PI
  3. Существует также формула Шриниваса Рамануджана для генерации ПИ, которая известна своей быстрой конвергенцией. Эта формула кажется сложной для реализации. Полагаю, мне бы здесь также пришлось повысить точность бейка.
    enter image description here

Итак, в любом случае, мне нужно было бы увеличить точность BigDecimal в зависимости от того, что является n-й цифрой. Как мне повысить точность BigDecimal до n-й цифры? Кроме того, если это будет лучше и быстрее, не могли бы вы указать мне правильное направление.

РЕДАКТИРОВАТЬ: я просто хочу генерировать PI. Я не хочу использовать для расчетов. и это вопрос о том, как я могу использовать BigDecimal для реализации моих идей по генерации PI.

Ответы [ 3 ]

6 голосов
/ 03 декабря 2011
  • Math.PI относится к типу double.Это означает около 15 десятичных цифр точности, и это все данные, которые у вас есть;ничто волшебным образом не приведет к появлению дополнительных цифр PI.
  • BigDecimal имеет произвольную точность.setScale() позволяет создавать BigDecimal объектов с любой необходимой точностью, и большинство арифметических методов автоматически увеличивают точность по мере необходимости, но, конечно, чем больше точность, тем медленнее будут все вычисления.
  • Самой сложной частью реализации формулы Рамануджана, по иронии судьбы, будет sqrt (2) в постоянном множителе, потому что для BigDecimal нет встроенной функции sqrt (), поэтому вам придется написать собственную.
3 голосов
/ 04 декабря 2011

Вам необходимо использовать MathContext для увеличения точности BigDecimal

например.

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

Важно, чтобы ВСЕ BigDecimal, которые вы используете в своих вычислениях, использовали это MathContext. Метод Герона должен дать вам 1000 цифр точности всего за 10 итераций и миллион цифр за 20 итераций, так что это, безусловно, достаточно хорошо. Также создайте все постоянные BigDecimal s, например, например. 26390 только один раз в начале вашей программы.

0 голосов
/ 27 июля 2013

Вы можете использовать этот код

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

ресурс

...