まず、円周率の任意の桁数が必要で、さまざまな浮動小数点数の精度に制限されたくない場合、円周率関数を任意の数値型ではなく文字列として定義します。
この手法を検索しているときに見つけた最も優れたアルゴリズムの 1 つは、Stanley Rabinowitz and Stan Wagon-Spigot Algorithmです。浮動小数点演算を必要とせず、ほとんどが反復的な方法です。中間計算で整数配列を格納するためのメモリが必要です。
コードの合理化やクリーンアップに時間をかけることなく、ここでアルゴリズムを実装します (結果に小数点が追加されないことに注意してください)。
このコードを個人的な目的以外で使用する場合は、必ずアルゴリズムとこのサイトを引用してください。
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桁までの最終バージョンをテストしました。