今、世界記録では、googleがgoogle cloud使って100兆桁求めたそうです。Chudnovskyのアルゴリズムを使って計算しているみたいですね。このアルゴリズムは、円周率計算ではメジャーなアルゴリズムっぽいです。
今回は、一桁一桁順繰り計算してくれる、spigotアルゴリズムってのがあるので、それを使って1万桁ぐらい計算してみます。
こちらのサイトで紹介していたプログラムを参考にしています。
詳しいことはこちらのサイトをご覧ください。
rustでSpigotアルゴリズムをやってみる
早速、このサイトに載ってる158byteで2400桁のC言語のプログラムをrustに移植。
fn main() {
let base:i64=10000;
let mut n:i64 = 8400;
let mut i;
let mut out=0;
let mut denom;
let mut numerator: [i64;8400]=[base/5;8400]; //分子の初期化
while n > 0 {
let mut temp=0;
i=n-1;
while i>0{
denom=2*i-1;
temp = temp*i+numerator[i as usize]*base;
numerator[i as usize]=temp%denom;
temp = temp/denom;
i-=1;
}
print!("{:>04}",out+temp/base);
out = temp % base;
n -= 14;
}
}
軽く解説します。
変数名などは、サイトの通りにしています。なので、一つ一つの変数の説明は、参考サイトをご覧ください。
参考サイトの場合、分子の初期化でループを回していますが、rustだと、宣言の時に一気に配列に数値を代入できるので、変数宣言時に処理をしています。
【for (n = 8400; n > 0; n -= 14)】みたいなforループは、rustではやりずらかったので、whileループで回しています。
rustのforループは、イテレーターがどっとかこっとかで・・・っていって、ほかのプログラムのときもデクリメントのforループで引っかかった気が・・・
結果としては、一瞬で2400桁なんて出てきます。目にも止まらず早業で
まとめ
さくっと、参考サイトのc言語のものをRustに移植してみました。
ざっくり数値をみてみても、円周率の計算は合っているようです。
Spigotアルゴリズムのプログラム方法は、ほかにもあるので、他のも試してみると面白いかもしれません。
Spigot以外にも円周率を計算するアルゴリズムは多数あります。それを実装していくのも面白いでしょうし、最新のものだけではなくて、古くからあるような、手計算でやっていたようなものを実際のプログラムで実装してみるのも面白いでしょう。
ではまた、
参考サイト・資料
サイト
書籍
・π‐魅惑の数 ジャン=ポール・ドゥラエ著 畑政義訳 朝倉書店
コメント