генерация пи до энной цифры java

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

  1. Используйте Math.PI и увеличьте точность (если это возможно)
  2. Используйте формулу Эйлера для получения числа пи, но даже здесь мне нужно было бы увеличить точность (я думаю) >
  3. Существует также формула Шринивасы Рамануджана для генерации PI, которая известна своей быстрой сходимостью. Эта формула кажется сложной для реализации. Я полагаю, что здесь мне также придется увеличить десятичную дробь.
    введите здесь описание изображения

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

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


person Jeel Shah    schedule 03.12.2011    source источник
comment
Вам действительно нужно генерировать число Пи или оно вам нужно для расчетов?   -  person Goran Jovic    schedule 03.12.2011
comment
Это вопрос о математике, лежащей в основе вычисления числа пи, или о том, как использовать BigDecimal?   -  person Oliver Charlesworth    schedule 03.12.2011
comment
Я просто использую BigDecimal для реализации формул PI, и мне не нужно вычислять PI, я просто хочу его сгенерировать.   -  person Jeel Shah    schedule 03.12.2011


Ответы (3)


  • Math.PI относится к типу double. Это означает точность около 15 знаков после запятой, и это все данные, которые у вас есть; ничто волшебным образом не заставит появиться дополнительные цифры PI.
  • BigDecimal имеет произвольную точность. setScale() позволяет создавать BigDecimal объектов с любой точностью, и большинство арифметических методов автоматически повышают точность по мере необходимости, но, конечно, чем выше точность, тем медленнее будут выполняться все вычисления.
  • По иронии судьбы, самой сложной частью реализации формулы Рамануджана будет sqrt(2) в постоянном множителе, потому что для BigDecimal нет встроенной функции sqrt(), так что вам придется написать свою собственную.
person Michael Borgwardt    schedule 03.12.2011
comment
Но для квадратного корня старый добрый метод Герона сходится достаточно быстро даже с точностью в миллион (или миллиард) знаков. - person Daniel Fischer; 03.12.2011
comment
для части sqrt (2), могу ли я просто использовать предопределенное значение? 1.41421356, или это как-то изменит расчет? - person Jeel Shah; 03.12.2011
comment
@ user681159: ну, как только вы захотите, чтобы ваше значение PI было более точным, чем это предопределенное значение, вам понадобится больше цифр sqrt (2). - person Michael Borgwardt; 03.12.2011
comment
@ user681159: Разве не очевидно, что если вы хотите рассчитать очень точный результат на основе определенного постоянного фактора, вы не можете сделать это с неточным приближением этого фактора? - person Michael Borgwardt; 03.12.2011
comment
извините, я пропустил это. Сделай мне слабину. - person Jeel Shah; 03.12.2011
comment
Что касается вашего последнего пункта, о том, что квадратный корень из 2 является самым сложным, не могли бы вы сделать BigDecimal sr2 = new BigDecimal(new BigDecimal(2).pow(1/2), MathContext(1000));, заменив 1000 с желаемой точностью? РЕДАКТИРОВАТЬ: Неважно, первый аргумент - это int, не позволяющий использовать рациональные показатели. - person tylerr147; 11.04.2019

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

e.g.

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

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

person SpiderPig    schedule 03.12.2011
comment
Что вы подразумеваете под методом Герона? - person Jeel Shah; 04.12.2011
comment
@ user681159 Метод Герона совпадает с методом Ньютона-Рафсона для случая квадратных корней, если вы знакомы с последним. В противном случае: он находит лучшие приближения к sqrt(a) через x_(n+1) = 1/2*(x_n + a/x_n). Он сходится для всех a > 0 и любого начального значения x_0 > 0. Если начать с достаточно хорошего приближения, на каждом шаге количество правильных цифр удваивается (приблизительно). - person Daniel Fischer; 04.12.2011

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

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

ресурс

person ggmax    schedule 27.07.2013
comment
Есть проблема с этим кодом, он приводит к бесконечному циклу при определенных условиях ;-( - person Werner Keil; 03.11.2016