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);
}