10億進法による十進浮動小数点ライブラリ

C/C++のlong double型ってどんな仕様なのかな?と調べてみたら普段使ってるgccだと80bitらしい。でもsizeof()で調べてみるとメモリサイズとしては128bit(16byte)だしなんだか中途半端な感じ。さらに調べてみたら128bit型はIEEE754で仕様が規定されてた。

IEEE754の128bitデータ型であれば必要十分な有効桁数が確保できるけど80bitだと国家予算程度でぎりぎりだしIEEE754の128bitデータ型が使えたとしても標準ライブラリの対応状況がびみょーな気も...

それと2進浮動小数点型は小数部を正確に表すことができないため十進浮動小数点型のほうが好ましいが普通の十進演算では十進数1桁毎に演算する必要があったりして効率が悪いのが気になってしまう。CPUも高速になってきているのでそう大きな問題でもなさそうではあるが...

そこで、ないものは作ればいいといつものいきおい(-_-;)で十進浮動小数点型で128bit以上を扱えて高速な演算が可能なデータ型を考えてみた。

高速な演算を行うには複数桁をまとめて演算する必要がある。そのため十進法ではなく十億進法を使い十進9桁をまとめて演算する方式にしてみた。64bit-CPUなら数兆や数京進法なども考えられるが浮動小数点型となると小数点の位置が一桁単位ではなく複数桁単位になってしまうことから有効桁数が数値により増減してしまうデメリットもあるので十億進法あたりが実用的な上限ではないかと思う。ちなみに32bitに十億を格納するのはビット利用率が高く収まりがいい。

数値は最上位桁から下位桁に向かって格納する。そうすることで演算時の桁合わせ処理が必要なくなるのと最上位桁だけでゼロ判定ができるので何かと都合が良い。それにともない小数点位置は最上位桁が小数点位置の起点となる。

まだ未完成の小数指数のべき乗(pow)のためのn乗根(root)が完成した段階でとりあえず公開することにしたけど、作りたてで試験もあまりしてないためバクバグしてる可能性があることに注意すること。

試しに512bitで2の平方根を求めてみた。ニュートン法による最大精度で求められた結果は136桁。512bitだと最大144桁であるが小数点位置の関係で144-8=136桁となる。

計算時間は1000回繰り返して約220msだったので一回あたり220usとなるが早いのか遅いのか比較対象がないのでわからない...

128bit 28桁 1.9us
256bit 64桁 10.7us
512bit 136桁 220.0us

1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641572735013846230912297024924836055850737

※ 浮動小数点型は表せる数値範囲は広いが有効桁が制限される。より大きな有効桁数を必要とするなら任意精度演算のほうが適している。

【仕様】

しかし、512bitで十億桁って一体どんな世界なんだろう?
想像もつきませーーーーーーーーーーーーーーーん。(笑)

【外部データ形式】

データは32bit値の配列[4-16]形式。

[999999999],[999999999],[999999999],[999999999],…

最上位桁:[仮数部(LSB:30bit)+指数部(1bit)+符号部(1bit)]
中下位桁:[仮数部(LSB:30bit)+指数部(2bit)]

桁(32bit)の仮数部には十億未満(999999999)の数値を格納。指数部は各桁に分割格納される。この形式は外部保存用の形式。

【内部データ形式】

外部データ形式と同じであるが演算しやすいよう各桁の符号部と指数部は別変数にまとめられ保存時に各桁に振り分けられる。

【オペレータ・オーバー・ロード】

ほとんどのオペレータをオーバーロードしてみたので標準データ型と同じようにコードが書けるし標準データ型との混在(型変換)も可能だがダウンキャスト時の数値のオーバーフローやアンダーフローには注意しなければならない。

【除算のアルゴリズム】

ライブラリを作るにあたって一番悩んだのは除算及び剰余処理だがなんとか完成。アルゴリズムはよく知られている筆算方式で十進一桁あたり1~3回の減算と4回の加算で処理している。128bitサイズだと全桁で9×4=36桁格納できるが全桁計算したとしても36回~108回の減算と144回の加算で済む。

小数部を含む剰余は除算と同じ処理で行えるが剰余を求める場合に限り商は整数に制限される。でないと何が余りかわからないので...

【サンプル・プログラム】

【ライブラリ】

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください