Как рассчитать PI в C #? - PullRequest
       263

Как рассчитать PI в C #?

27 голосов
/ 02 сентября 2008

Как я могу рассчитать значение PI, используя C #?

Я думал, что это будет через рекурсивную функцию, и если да, то как бы это выглядело, и есть ли математические уравнения, подтверждающие это?

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

Ответы [ 21 ]

1 голос
/ 02 ноября 2014
    public static string PiNumberFinder(int digitNumber)
    {
        string piNumber = "3,";
        int dividedBy = 11080585;
        int divisor = 78256779;
        int result;

        for (int i = 0; i < digitNumber; i++)
        {
            if (dividedBy < divisor)
                dividedBy *= 10;

            result = dividedBy / divisor;

            string resultString = result.ToString();
            piNumber += resultString;

            dividedBy = dividedBy - divisor * result;
        }

        return piNumber;
    }
1 голос
/ 05 ноября 2010
Enumerable.Range(0, 100000000).Aggregate(0d, (tot, next) => tot += Math.Pow(-1d, next)/(2*next + 1)*4)
0 голосов
/ 12 мая 2018

Вот хороший способ: Рассчитайте ряд 1 / x ^ 2 для x от 1 до того, что вы хотите - чем больше число, тем лучше результат. Умножьте результат на 6 и до sqrt (). Вот код на c # (только основной):

static void Main(string[] args)
    {
        double counter = 0;
        for (double i = 1; i < 1000000; i++)
        {

            counter = counter + (1 / (Math.Pow(i, 2)));

        }
        counter = counter * 6;
        counter = Math.Sqrt(counter);
        Console.WriteLine(counter);
    }
0 голосов
/ 16 марта 2018

PI (π) можно рассчитать, используя бесконечный ряд . Вот два примера:

Серия Грегори-Лейбница:

π / 4 = 1 - 1/3 + 1/5 - 1/7 + 1/9 - ...

C # метод:

public static decimal GregoryLeibnizGetPI(int n)
{
    decimal sum = 0;
    decimal temp = 0;
    for (int i = 0; i < n; i++)
    {
        temp = 4m / (1 + 2 * i);
        sum += i % 2 == 0 ? temp : -temp;
    }
    return sum;
}

Серия Нилаканта:

π = 3 + 4 / (2x3x4) - 4 / (4x5x6) + 4 / (6x7x8) - 4 / (8x9x10) + ...

C # метод:

public static decimal NilakanthaGetPI(int n)
{
    decimal sum = 0;
    decimal temp = 0;
    decimal a = 2, b = 3, c = 4;
    for (int i = 0; i < n; i++)
    {
        temp = 4 / (a * b * c);
        sum += i % 2 == 0 ? temp : -temp;
        a += 2; b += 2; c += 2;
    }
    return 3 + sum;
}

Входной параметр n для обеих функций представляет количество итераций.

Серия Nilakantha по сравнению с серией Грегори-Лейбница сходится быстрее. Методы могут быть проверены с помощью следующего кода:

static void Main(string[] args)
{
    const decimal pi = 3.1415926535897932384626433832m;
    Console.WriteLine($"PI = {pi}");

    //Nilakantha Series
    int iterationsN = 100;
    decimal nilakanthaPI = NilakanthaGetPI(iterationsN);
    decimal CalcErrorNilakantha = pi - nilakanthaPI;
    Console.WriteLine($"\nNilakantha Series -> PI = {nilakanthaPI}");
    Console.WriteLine($"Calculation error = {CalcErrorNilakantha}");
    int numDecNilakantha = pi.ToString().Zip(nilakanthaPI.ToString(), (x, y) => x == y).TakeWhile(x => x).Count() - 2;
    Console.WriteLine($"Number of correct decimals = {numDecNilakantha}");
    Console.WriteLine($"Number of iterations = {iterationsN}");

    //Gregory-Leibniz Series
    int iterationsGL = 1000000;
    decimal GregoryLeibnizPI = GregoryLeibnizGetPI(iterationsGL);
    decimal CalcErrorGregoryLeibniz = pi - GregoryLeibnizPI;
    Console.WriteLine($"\nGregory-Leibniz Series -> PI = {GregoryLeibnizPI}");
    Console.WriteLine($"Calculation error = {CalcErrorGregoryLeibniz}");
    int numDecGregoryLeibniz = pi.ToString().Zip(GregoryLeibnizPI.ToString(), (x, y) => x == y).TakeWhile(x => x).Count() - 2;
    Console.WriteLine($"Number of correct decimals = {numDecGregoryLeibniz}");
    Console.WriteLine($"Number of iterations = {iterationsGL}");

    Console.ReadKey();
}

Следующий вывод показывает, что Nilakantha Series возвращает шесть правильных десятичных знаков PI с сотней итераций, тогда как Gregory-Leibniz Series возвращает пять правильных десятичных знаков PI с миллионом итераций:

enter image description here

Мой код можно протестировать >> здесь

0 голосов
/ 19 ноября 2016

Во-первых, обратите внимание, что C # может использовать поле Math.PI .NET Framework:

https://msdn.microsoft.com/en-us/library/system.math.pi(v=vs.110).aspx

Приятной особенностью здесь является то, что это двойная точность с полной точностью, которую вы можете использовать или сравнить с вычисленными результатами. Вкладки по этому URL имеют аналогичные константы для C ++, F # и Visual Basic.

Чтобы рассчитать больше мест, вы можете написать свой собственный код с расширенной точностью. Тот, который быстро кодировать и достаточно быстро и легко программировать:

Pi = 4 * [4 * арктан (1/5) - арктан (1/239)]

Эта формула и многие другие, включая те, которые сходятся с удивительно высокой скоростью, например, 50 цифр в семестре, в Wolfram:

Формулы Вольфрама Пи

0 голосов
/ 18 июня 2012

Мне нравится эта статья , которая объясняет, как вычислить π на основе разложения в ряд Тейлора для Арктангента.

Статья начинается с простого предположения, что

Атан (1) = π / 4 радиана

Атан (x) может быть итеративно оценен с помощью ряда Тейлора

атан (х) = х - х ^ 3/3 + х ^ 5/5 - х ^ 7/7 + х ^ 9/9 ...

В статье указывается, почему это не особенно эффективно, и продолжается ряд логических улучшений в технике. Они также предоставляют пример программы, которая вычисляет π до нескольких тысяч цифр, с исходным кодом, включая требуемые математические процедуры бесконечной точности.

0 голосов
/ 11 июля 2011

Следующая ссылка показывает, как вычислить константу pi на основе ее определения как интеграла, который можно записать как предел суммирования, это очень интересно: https://sites.google.com/site/rcorcs/posts/calculatingthepiconstant Файл «Pi как интеграл» объясняет этот метод, используемый в этом посте.

0 голосов
/ 02 сентября 2008

В любом производственном сценарии я заставляю вас искать значение с желаемым количеством десятичных знаков и сохранять его как «const» там, где ваши классы могут добраться до него.

(если вы не пишете научное программное обеспечение для "Пи" ...)

0 голосов
/ 03 сентября 2008

@ Томас Каммейер:

Обратите внимание, что Atan (1.0) довольно часто жестко запрограммирован, поэтому 4 * Atan (1.0) на самом деле не является "алгоритмом", если вы вызываете библиотечную функцию Atan (довольно много уже предложенных действительно продолжаются заменой Atan x) по серии (или бесконечному произведению) для него, затем оценивая его при x = 1.

Кроме того, очень мало случаев, когда вам понадобится пи с большей точностью, чем несколько десятков бит (которые могут быть легко закодированы!). Я работал над приложениями в математике, где, чтобы вычислить некоторые (довольно сложные) математические объекты (которые были полиномиальными с целыми коэффициентами), мне пришлось выполнять арифметику с действительными и комплексными числами (включая вычисление числа пи) с точностью до несколько миллионов бит ... но это не очень часто "в реальной жизни":)

Вы можете посмотреть следующий пример код .

0 голосов
/ 02 сентября 2008
public double PI = 22.0 / 7.0;
...