尝试使用C#计算Pi到N的小数位数

时间:2010-02-09 01:48:35

标签: c# algorithm pi

注意:我已经阅读了this topic,但我不明白它并没有提供我可以使用的解决方案。数字问题我很糟糕。

将Pi生成为用户想要的小数位数的简单方法是什么?这不是为了完成家庭作业,只是想完成这里列出的一些项目:

Link

3 个答案:

答案 0 :(得分:6)

用于计算pi的数字的经典算法是Gauss-Legendre算法。虽然它没有一些更现代的算法那么快,但确实具有可理解的优点。

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#,包括发现一个任意精度的算术库。

答案 1 :(得分:2)

The topic your talking about使用泰勒系列计算PI的值。在该主题上使用函数“double F(int i)”将为您提供“i”项后的PI值。

这种计算PI的方式有点慢,我建议你看一下PI fast algorithm

您还可以找到一个实现here,将计算PI提升到第n位。

祝你好运!

答案 2 :(得分:1)

如果你仔细研究这个非常好的指南:

Patterns for Parallel Programming: Understanding and Applying Parallel Patterns with the .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;
}