Попытка вычислить число от Пи до N десятичных знаков с помощью C # - PullRequest
1 голос
/ 09 февраля 2010

Примечание: я уже прочитал эту тему , но я ее не понимаю и не предлагает решения, которое мог бы использовать У меня ужасные проблемы с номером.

Какой простой способ сгенерировать число Пи с тем количеством разрядов, которое хочет пользователь? Это не для домашней работы, просто пытаюсь завершить некоторые из проектов, перечисленных здесь:

Ссылка

Ответы [ 3 ]

6 голосов
/ 09 февраля 2010

Классическим алгоритмом для вычисления цифр pi является алгоритм Гаусса-Лежандра. Хотя он не такой быстрый, как некоторые из более современных алгоритмов, он имеет преимущество в том, что он понятен.

Пусть

a_0 = 1
b_0 = 1/Sqrt(2)
t_0 = 1/4
p_0 = 1

Тогда

a_(n+1) = (a_n + b_n) / 2
b_(n+1) = Sqrt(a_n * b_n)
t_(n+1) = t_n - p_n * (a_n - a_(n+1))^2
p_(n+1) = 2 * p_n

Тогда

pi =. (a_n + b_n)^2 / (4 * t_n)

Здесь (=. означает «приблизительно равно»). Этот алгоритм демонстрирует квадратичную сходимость (число правильных десятичных знаков удваивается с каждой итерацией).

Я предоставлю вам возможность перевести это на C #, включая обнаружение арифметической библиотеки произвольной точности.

2 голосов
/ 09 февраля 2010

Тема, о которой вы говорите Рассчитайте значение PI, используя ряд Тейлора. Использование функции «double F (int i)», написанной на эту тему, даст вам значение PI после термина «i».

Этот способ вычисления PI довольно медленный, я предлагаю вам взглянуть на быстрый алгоритм PI .

Вы также можете найти одну реализацию здесь , которая переводит PI в n-ю цифру.

Удачи!

1 голос
/ 26 ноября 2010

Если вы внимательно посмотрите на это действительно хорошее руководство:

Шаблоны для параллельного программирования: понимание и применение параллельных шаблонов в .NET Framework 4

Вы найдете на этой странице симпатичную реализацию (с небольшими изменениями с моей стороны):

static decimal ParallelPartitionerPi(int steps)
{
    decimal sum = 0.0;
    decimal step = 1.0 / (decimal)steps;
    object obj = new object();
    Parallel.ForEach(Partitioner.Create(0, steps),
        () => 0.0,
        (range, state, partial) =>
            {
                for (int i = range.Item1; i < range.Item2; i++)
            {
                decimal x = (i + 0.5) * step;
                partial += 4.0 / (1.0 + x * x);
            }
            return partial;
        },
        partial => { lock (obj) sum += partial; });
    return step * sum;
}
...