如何计算C#中的PI?

如何计算C#中的PI?,c#,pi,C#,Pi,如何使用C#计算PI的值 我想它应该是通过一个递归函数来实现的,如果是的话,它会是什么样子?有什么数学方程来支持它吗 我对表现不太挑剔,主要是从学习的角度考虑如何表现。计算如下: x = 1 - 1/3 + 1/5 - 1/7 + 1/9 (... etc as far as possible.) PI = x * 4 你有圆周率 这是我所知道的最简单的方法 PI的值慢慢收敛到PI的实际值(3.141592165…)。如果迭代次数越多越好。如果需要递归: PI = 2 * (1 + 1/3

如何使用C#计算PI的值

我想它应该是通过一个递归函数来实现的,如果是的话,它会是什么样子?有什么数学方程来支持它吗

我对表现不太挑剔,主要是从学习的角度考虑如何表现。

计算如下:

x = 1 - 1/3 + 1/5 - 1/7 + 1/9  (... etc as far as possible.)
PI = x * 4
你有圆周率

这是我所知道的最简单的方法

PI的值慢慢收敛到PI的实际值(3.141592165…)。如果迭代次数越多越好。

如果需要递归:

PI = 2 * (1 + 1/3 * (1 + 2/5 * (1 + 3/7 * (...))))
经过改写后,这将变成:

PI = 2 * F(1);
连同F(i):

艾萨克·牛顿(你以前可能听说过他)想出了这个窍门。 注意,为了保持简单,我省略了结束条件。在现实生活中,你需要一个。

如何使用:

double pi = Math.PI;

如果您想要比这更高的精度,您需要使用算法系统和十进制类型。

在任何生产场景中,我都会强制您查找所需的小数点数量,并将其作为“常量”存储在您的类可以访问的某个位置


(除非您正在编写科学的“Pi”特定软件…

不同算法的良好概述:

  • )
我不确定Gauss-Legendre-Salamin算法在第一个链接中声称的复杂性(我可以说是O(N log^2(N)log(log(N)))

不过,我鼓励您尝试一下,收敛速度非常快

另外,我也不太清楚为什么要尝试将一个非常简单的过程算法转换为递归算法

请注意,如果您对性能感兴趣,那么以有界精度工作(通常,需要“双精度”、“浮点”和…输出)并没有真正的意义,因为在这种情况下,显而易见的答案就是对值进行硬编码。

关于

public double PI = 22.0 / 7.0;
。。。如何从学习的角度出发

你在尝试学习规划科学方法吗?还是生产生产软件?我希望社区将此视为一个合理的问题,而不是吹毛求疵

无论是哪种情况,我认为编写自己的Pi都是一个已解决的问题。Dmitry已经显示了'Math.PI'常量。在同一空间攻击另一个问题!找一个通用的牛顿近似法或一些巧妙的方法。

这里有一个很好的方法(来自);它的收敛速度比上面讨论的简单公式要快得多,如果您的目的是将递归作为一种学习练习,那么它非常适合于递归解决方案。(假设您正在学习经验,我不会给出任何实际代码。)

基本公式与上面相同,但此方法对部分和进行平均,以加速收敛

定义双参数函数pie(h,w),以便:

pie(0,1) = 4/1
pie(0,2) = 4/1 - 4/3
pie(0,3) = 4/1 - 4/3 + 4/5
pie(0,4) = 4/1 - 4/3 + 4/5 - 4/7
... and so on
因此,探索递归的第一个机会是编写“水平”计算代码,随着“宽度”参数的增加(对于“高度”为零)

然后使用以下公式添加第二个维度:

pie(h, w) = (pie(h-1,w) + pie(h-1,w+1)) / 2
当然,它只用于大于零的h值


这个算法的好处在于,当您探索由逐渐增大的参数产生的结果时,您可以轻松地用电子表格对其进行模拟,以检查代码。当您计算pie(10,10)时,您将得到一个对于大多数工程目的来说足够好的pi的近似值。

什么是pi?圆的周长除以其直径

在计算机图形学中,您可以从初始点x,y绘制一个圆心为0,0的圆,下一个点x',y'可以使用一个简单的公式找到: x'=x+y/h:y'=y-x'/h


h通常是2的幂,因此可以通过移位(或从双精度上的指数中减去)轻松地进行除法。h也是圆的半径r。一个简单的起点是x=r,y=0,然后计算c的步数,直到x这里有一些非常非常古老的技巧,我很惊讶这里没有看到

atan(1)==PI/4,因此当可靠的反正切函数 现在是4*atan(1)

这是一个非常可爱的固定比率估计值,使旧的西部22/7看起来像灰尘 是355/113,可以精确到小数点后几位(我想至少三到四位)。 在某些情况下,这对于整数运算来说已经足够好了:乘以355,然后除以113

355/113也很容易记忆(对某些人来说):数一、一、三、三、五、五,记住你是用分母和分子来命名数字的(如果你忘了哪个三元组在上面,一微秒的思考通常会把它理顺)

请注意,22/7给出了:3.14285714,这是错误的千分之一

355/113给出了3.14159292,这在千万分之一之前都是正确的

根据我方框中的/usr/include/math.h,M#PI定义为: 3.14159265358979323846 就目前而言,这可能是件好事

你从估算PI中得到的教训是,有很多方法可以做到这一点, 没有一个是完美的,你必须根据预期用途来分类

355/113是一个古老的中国估算,我相信它比22/7早很多年。它是我读大学时一位物理教授教我的。

@Thomas Kammeyer:

请注意,Atan(1.0)通常是硬编码的,因此,如果您调用库Atan函数,那么4*Atan(1.0)并不是一个真正的“算法”(很多人已经建议确实要用一个系列(或无限乘积)替换Atan(x),然后在x=1时对其求值)

此外,很少有情况下需要比几十位精度更高的pi(这可以很容易地硬编码!)。我在数学应用程序中工作过,计算一些(相当复杂的)数学对象(具有整数系数的多项式),我不得不对实数和复数做算术
pie(h, w) = (pie(h-1,w) + pie(h-1,w+1)) / 2
Enumerable.Range(0, 100000000).Aggregate(0d, (tot, next) => tot += Math.Pow(-1d, next)/(2*next + 1)*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;
}
using System;

namespace Strings
{
    class Program
    {
        static void Main(string[] args)
        {

/*          decimal pie = 1; 
            decimal e = -1;
*/
            var stopwatch = new System.Diagnostics.Stopwatch();
            stopwatch.Start(); //added this nice stopwatch start routine 

  //leibniz formula in C# - code written completely by Todd Mandell 2014
/*
            for (decimal f = (e += 2); f < 1000001; f++)
            {
                 e += 2;
                 pie -= 1 / e;
                 e += 2;
                 pie += 1 / e;
                 Console.WriteLine(pie * 4);
            }

                 decimal finalDisplayString = (pie * 4);
                 Console.WriteLine("pie = {0}", finalDisplayString);
                 Console.WriteLine("Accuracy resulting from approximately {0} steps", e/4); 
*/

// Nilakantha formula - code written completely by Todd Mandell 2014
// π = 3 + 4/(2*3*4) - 4/(4*5*6) + 4/(6*7*8) - 4/(8*9*10) + 4/(10*11*12) - (4/(12*13*14) etc

            decimal pie = 0;
            decimal a = 2;
            decimal b = 3;
            decimal c = 4;
            decimal e = 1;

            for (decimal f = (e += 1); f < 100000; f++) 
            // Increase f where "f < 100000" to increase number of steps
            {

                pie += 4 / (a * b * c);

                a += 2;
                b += 2;
                c += 2;

                pie -= 4 / (a * b * c);

                a += 2;
                b += 2;
                c += 2;

                e += 1;
            }

            decimal finalDisplayString = (pie + 3);
            Console.WriteLine("pie = {0}", finalDisplayString);
            Console.WriteLine("Accuracy resulting from {0} steps", e); 

            stopwatch.Stop();
            TimeSpan ts = stopwatch.Elapsed;
            Console.WriteLine("Calc Time {0}", ts); 

            Console.ReadLine();

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