Вопрос

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

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

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

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

Это было полезно?

Решение

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

Другие советы

Вам нужно использовать MathContext Чтобы повысить точность BigDecimal

например

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

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

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

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

ресурс

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top