using namespace OTL;
ことのほったんは,昨日の地下室にて。IndexBoardを実装するとき3^nをtemplate引数に渡そうとしたら,うーん,どうしよう。template引数じゃ関数で書けないし。。しかしまて,3^nってtemplateでかけるんじゃないのか。ってことで,まずはpower
templateclass power { public: static const int val = N * power ::val; }; template class power { public: static const int val = N; };
部分特殊化はクラスにしかできない。最初は関数オブジェクトにしていたが,それじゃtemplateに渡せないんでstatic constにしたら通りましたと。
こんなに見事にできるとは思っていなかったんで,調子に乗ってfibやfactも完成。だんだん盛り上がってくると,もっとすごいことできないかと。そうだ! πを計算しよう。なるたけ簡単な展開公式を探すと,分数のみで展開できるらしい。
templatestruct iter_pi { static const double val = 4.0/(4*N+1) - 4.0/(4*N+3) + iter_pi ::val; }; template struct iter_pi { static const double val = 0; };
残念ながら,gccのtemplate展開は最大で500こまでっぽかったので(後に,最大ではんなくて連続でなのかもしれない?),ふつうにやると3.13までしか達成せず。そこで,上の1手展開して状態でiter_pi<0, 400>にし,ついに3.14達成! その後,もっと深く計算できる方法も発見できたり。
なんか,この辺のこと論理演習でやったような気がしてきたぞ。ここら辺駆使したら,素数判定とかできるんじゃないのかとか言い出す。
templatestruct is_prime { static const bool val = (N % M != 0) && is_prime ::val; }; template struct is_prime { static const bool val = true; };
ってことはだ,N番目の素数も出せるんじゃん?? そのためには,if文が必要だったりするのだが,trueもfalseも評価してしまうと,if文を作れない! どっかの演習でやりましたね。ついに断念かと思ったが,trueならデクリメントしてfalseならデクリメントしない。ということは,conditionの結果を引き算すればいいじゃん!
templatestruct nth_prime { static const int val = nth_prime ::val>::val; }; template struct nth_prime { static const int val = N-1; };
やった! 30番目の素数は113だそうだ。
そういや,sinも展開できるな。
templatestruct iter_sin { static const double x = to_radian ::val; static const double val = x / fact<2*N+1>::val - x * x * iter_sin ::val; }; template struct iter_sin { static const double val = 0; };
sin 30°は0.499955らしい。すばらしい。
とまぁ,こんなことして結局IndexBoardなんぞできなかった一日でした。F氏とかいたら,もっともりあがっていたんだろうに。