optionalを使ってみる
ついうっかりオーバーフローしてしまって0点、というのが頻出はまりパターンなので、optioalを使ってMaybeモナド的な整数型を作ればいいんじゃないかと思った。というわけで「掛け算はオーバーフローする可能性がある」ということを忘れずにいられる型ができた。if(x)で確認してから*xしないと値を取り出せないので「オーバーフローしているかもしれない整数」から「オーバーフローしていないことを確認」してから「オーバーフローしていない整数型」に変換して使うことになる。
#include<boost/optional.hpp> using namespace boost; typedef long long LL; typedef optional<LL> OLL; // optional<long long>の掛け算 OLL mul(OLL x, OLL y){ if(!x) return x; if(!y) return y; LL result = (*x) * (*y); if(result / (*x) != (*y)){ // overflow return OLL(); } return OLL(result); } // long longでのpow. OLL llpow(OLL n, size_t m){ if(m == 0) return OLL(1); if(m == 1) return n; return mul(n, llpow(n, m - 1)); } OLL llpow(LL n, size_t m){ return llpow(OLL(n), m); }