首先,假设您想要 pi 的任意位数,并且我们不希望受限于任何各种浮点数的精度,让我们将 Pi 函数定义为字符串而不是任何数字类型。
我在搜索这项技术时发现的最酷的算法之一是Stanley Rabinowitz 和 Stan Wagon-Spigot 算法。它不需要浮点数学,并且主要是一种迭代方法。它确实需要一些内存来在中间计算中存储整数数组。
无需花时间精简或清理代码,这里是算法的实现(注意结果不添加小数点)。
如果您打算将此代码用于个人用途以外的任何用途,请务必引用算法和本网站。
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 位数的最终版本。