ちょっと脱線だが、C++のテンプレート・メタ・プログラミングを利用して
コンパイル時にdoubleやfloatの計算ができるライブラリを作ってみた。
取り敢えずはコンパイル時計算によるFFTの最適化という自分の研究のために作ったので
今のところ四則演算と整数との変換とsinhp()の計算しかまだ実装してないし、
丸めは直近だけだしNaNとか非正規化数とか実装してないんだが…。
ちゃんと整備したら使う人いそうかな?
>>477 >コンパイル時にdoubleやfloatの計算ができるライブラリを作ってみた。
イメージが湧かねぇ・・・
概略を教えて。
C++のtemplate駆使するとフィボナッチ数列もコンパイル時に評価できるらしいが正直どうでもいいや。
そういや昔Perlでヘッダ出力するスクリプト作ったけどそんなんで十分だな。
>>477 公開キボン。ゲーム屋なんで使うこともあるかもしれん。
>>480 実際に公開するとなると整備しないといけないことはまだまだ多かったりしますが・・・。
・namespaceをちゃんと使う。
・名前の整理(わかりにくい命名を直す。)
・floatをちゃんとテストする(実はdoubleが必要だったのでfloatは雑にしかテストしてない。)
・sin()以外の初等関数の実装。
・丸めモードの実装
・NaNや非正規化数の実装
・g++×Windows×x86環境以外で動かすテストと修正(ポケット・マネーではつらい予感。特にx86以外のプロセッサ。)
・64bit整数型がない環境への対応(多分これがプログラミング作業的には一番面倒)
>>478 template<typename prec, int sign, int exp, typename fraction>
struct StaticReal{
static const int s = sign;
static const int e = exp;
typedef fraction f;
};
って感じです。
precは精度を指定するテンプレート・パラメータです。
(doubleとかfloatとかを指定します。)
小数部をあらわすfractionが基本型でなく
typedefになっているのはIEEE準拠のdoubleの実装には
64bitを超える結果を返す正確な整数演算が必要だったため、
それもクラス・テンプレートで実装する必要があったからです。
具体的な各浮動小数点数値はこのテンプレートの特殊バージョンとして与えられます。
>>482の続き
計算はa,b,xが上記のように定義されたテンプレートの特殊バージョンを表すtypedef名だとすると。
AddStaticReal<a,b>::result
とか
SinhpStaticReal<x>::result
のように実行します。結果もテンプレートの特殊バージョンのtypedef名です。
なので「値」を変数に覚えておくには
typedef SinhpStaticReal<x>::result r;
のようにします。typedefなんで代入はなしで初期化のみ。
FromStaticReal<r>::get()
とやると対応するdouble型の値が得られます。
>>483 で静的メンバ関数get()を実行するまではどんな「浮動小数点演算」もコンパイラが計算しますから
実行時の立場から見れば単に整数定数だけを含むクラス定義の集まりということになります。
get()はその整数定数から実行時に浮動小数点型doubleやfloatの値を組み立てます。
ちなみにsinhp()は
>>476で述べたような多少仕様にヒネリのあるsin()関数です。