在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
等等。
我不在乎程序的速度。我只希望它尽可能简单易懂。提前感谢你的帮助。
6条答案
按热度按时间gcmastyq1#
首先,假设你想要任意位数的pi,并且我们不想被限制在任何一个浮点数的精度上,让我们把一个Pi函数定义为一个字符串,而不是任何数字类型。
我在寻找这种技术时发现的最酷的算法之一是Stanley Rabinowitz and Stan Wagon - Spigot Algorithm,它不需要浮点运算,主要是一种迭代方法,但在中间计算中需要一些内存来存储整数数组。
这里没有花时间简化或清理代码,而是实现了该算法(注意,结果没有添加小数点)。
请务必引用算法和本网站如果您打算使用此代码以外的任何个人使用。
C#代码
更新
我终于开始修复35位之后发生的“进位错误”。链接文档的第6页,事实上,专门谈到了这里发生的事情。我已经测试了最终版本好到1000位。
6ss1mwsb2#
如果你需要更高的精度,你会在使用double数据类型时遇到麻烦,因为它支持一个特定的最大精度(由Math.PI提供)。
k3bvogb13#
经过大量的搜索,我发现了这个小片段:
到目前为止,它的工作非常有魅力。您只需要从GAC添加System.Numerics库就可以解析BigInteger类型。
x6492ojm4#
与nicholas相同的算法,但使用yield进行延迟计算
我使用short.MaxValue作为位置数的上限,但这是因为我的机器虚拟内存不足,更好的机器应该能够容纳最多int.MaxValue。
该函数可以这样调用:
pjngdqdw5#
如果您对本机数学库提供的位数感到满意,那么它就很简单;如果你需要更多的位数(几十位、几百位或几千位),你需要一个一次吐出一位数的spigot算法。Jeremy Gibbons在我的博客上给出了一个algorithm,我implementtwice,在我的博客上你可以找到Scheme、C、Python、Haskell、Perl和Forth(抱歉,不是C#)的代码。
xlpyo6sf6#
最简单的方法是将大量的数字pi存储在一个String常量中,然后当你需要
n
位数精度时,你只需要从0到n+2
取一个子串。