c# - 如何使用循环在 C# 中计算 pi 到 N 个位置

标签 c# .net algorithm math loops

我如何在 C# 中计算 PI 到特定的小数位?

我希望能够将一个数字传递给一个方法并返回计算到该小数位数的 PI。

public decimal CalculatePi(int places)
{
    // magic
    return pi;
}

Console.WriteLine(CalculatePi(5)); // Would print 3.14159

Console.WriteLine(CalculatePi(10)); // Would print 3.1415926535

等...

我不关心程序的速度。我只是希望它尽可能简单易懂。预先感谢您的帮助。

最佳答案

首先,假设您想要 pi 的任意位数,并且我们不想受任何各种 float 精度的限制,让我们将 Pi 函数定义为字符串而不是任何数字类型。

我在搜索此技术时发现的最酷的算法之一是 Stanley Rabinowitz and Stan Wagon - Spigot Algorithm .它不需要 float 学运算,主要是一种迭代方法。它确实需要一些内存来存储中间计算中的整数数组。

在不花时间精简或清理代码的情况下,这里是算法的实现(注意结果不添加小数点)。

如果您打算将此代码用于除个人用途以外的任何用途,请务必引用算法和此站点。

C#代码

public static string CalculatePi(int digits)
{   
    digits++;

    uint[] x = new uint[digits*10/3+2];
    uint[] r = new uint[digits*10/3+2];
    
    uint[] pi = new uint[digits];

    for (int j = 0; j < x.Length; j++)
        x[j] = 20;
        
    for (int i = 0; i < digits; i++)
    {
        uint carry = 0;
        for (int j = 0; j < x.Length; j++)
        {
            uint num = (uint)(x.Length - j - 1);
            uint dem = num * 2 + 1;

            x[j] += carry;

            uint q = x[j] / dem;
            r[j] = x[j] % dem;

            carry = q * num;
        }
        
        
        pi[i] = (x[x.Length-1] / 10);
            
                    
        r[x.Length - 1] = x[x.Length - 1] % 10; ;
        
        for (int j = 0; j < x.Length; j++)
            x[j] = r[j] * 10;
    }
    
    var result = "";
    
    uint c = 0;
    
    for(int i = pi.Length - 1; i >=0; i--)
    {
        pi[i] += c;
        c = pi[i] / 10;
        
        result = (pi[i] % 10).ToString() + result;
    }

    return result;
}

更新

我终于开始解决 35 位数字后发生的“进位错误”。链接文档的第 6 页,实际上专门讲了这里发生的事情。我已经测试了最终版本好到 1000 位。

关于c# - 如何使用循环在 C# 中计算 pi 到 N 个位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11677369/

相关文章:

c# - Azure Functions V1 DI 的依赖项注入(inject)

c# - 如何使用 async/await OnNext/OnError/OnCompleted 方法实现 IObserver?

algorithm - 如何使用分布排序(基数排序等)对字符串进行排序?

c++ - 如何在 Gecode 中实现 'nested' 成本函数?

c# - 如何使用最少的锁定访问文件

c# - 构建通用集合类

使用 LINQ 删除 C# 数据集列

c# - 一个月过去了吗?

c# - 用于拆分大写字符字符串的自定义函数无法按预期工作

c# - 启动时启动应用程序,使用错误的路径加载