BBPアルゴリズムに依るパイ計算は結果が16進数で得られます。AVR(ATmega168)で計算させて出てきた円周率は16進数で表示されます。これを10進数で表示させてみようと16進数から10進数に直すプログラムを作っていました。hexの取り込み部分がうまく機能していませんでしたが何とか取り込みが出来ました。
取りあえず、結果が出たかな?HEXだと4000桁(時間は掛かりますが)と凄い桁数がでますが、10進数への変換では6桁までそれ以上は誤差含みの値になってしまう様です。(私の単純な計算法ではここまでです)
これが得られた結論です。
これは、パソコンのGCC環境でも、avr-gccでも違いはありません。ただし
AVR-GCCでは、double == floatなので、誤差のでる桁数はパソコンの
GCCの半分程度となります。
しかし、整数の任意精度の計算を整数で実現すれば、時間はかかりますが
問題なく計算できます。
ラジオ少年さんが、別のロジックで計算したのは、そうしたアルゴリズムを
採用しています。
任意精度の演算をAVRマイコンのようにRAMが少ない環境で実現するかが
腕の見せ所なわけです。
>ラジオ少年さんが、別のロジックで計算したのは、そうしたアルゴリズムを採用しています。
そう言うことですね。少しだけこの辺の所が分かりました。
こちらの多倍長整数型のプログラムを使えば多桁も可能かもしれませんが、やはり、メモリを多く使うのでAVRでは厳しいかもしれません。
とりあえず、パソコン(Mac)上のgcc環境ではこのプログラムの動作を確認してBBPアルゴリズムによるパイ計算の16進数から10進数変換は出来ました。(16進20桁分)
16進20桁分を10進数に変換出来たとのこと了解です。
私の場合プログラムの知識はあまり有りませんので多倍長整数型と何ぞやから始めないと行けません。
URLをご紹介下さいましたので調べてみます。
>変換した10進数の何桁目までがπとして正しい値なのかどうやって判断するかが問題です。
そうですね、計算の過程でいつ誤差が発生するかが分からないと何桁目まで正しいのか判断出来ませんね。
私には益々難しくなります。
まず、マイコンで少数を扱うのは大変ですし、処理速度も遅くなります。
そこで計算前に分子(割られる数)を1000倍や10000倍してから割り算をすれば本来の小数部が整数として扱えます。
扱う小数部の桁が少なければlong型で足りますが、今回のような場合はlong型では不足です。
そこで多倍長整数型が必要になります。
多倍長整数型は配列を使ってlong型を超える整数を扱えるようにした方法です。
多倍長整数型を利用すれば、計算前に1000000000倍以上が可能になります。
BBPアルゴリズムで得られた1桁を1000000000倍以上で乗算した後に16進数の小数部の重みで割れば10進数になり、小数部が整数化されます。
あとは整数化された小数部を足していけば良いわけです。
私のやった筆算アルゴリズムでは6桁がいいところですが、多倍長整数型を使えばメモリの少ないAVRでももう数桁は増やせるのではないかと思います。
多倍長整数型をプログラム上にどの様に書いたらいいのか?この辺から少し取り組んで見ます。
アドバイス有り難うございました。
↑にパソコン上で動作する多倍長整数型を使ったプログラムを置きました。
解凍したらsource6ディレクトリでmakeして、その後にsource6の上のディレクトリでmakeしてください。
実行ファイルはlongintです。
実行すると色々と表示しますが、最後の1行がパイの小数部です。
後程やってみます。
< x: >
+1415 9265 3589 7932 3846 2643 3832 7950 2876