User-defined literals で固定長の Boost.Multiprecision を生成
template
template<char ...cs> constexpr std::size_t operator "" _cpp_int(){ return sizeof...(cs); } static_assert(1234_cpp_int == 4, ""); static_assert(123456789_cpp_int == 9, "");
で、その数値の桁数からビット幅を計算して固定長の Boost.Multiprecision を生成出来ないかなーと思ってやってみたんですがビット幅を取得する計算方法がよく分からなかったのでとりあえず適当にやってみた/(^o^)\
やや多めのビット幅で定義するけど一応は動作するはず。
[ソース]
#include <boost/multiprecision/cpp_int.hpp> #include <iostream> template<int Precision> using cpp_int = boost::multiprecision::number< boost::multiprecision::cpp_int_backend< Precision, Precision, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void > >; template<char ...cs> cpp_int<std::size_t(sizeof...(cs) * 3.34)> operator "" _cpp_int(){ char const str[] = { cs..., '\0' }; return cpp_int<std::size_t(sizeof...(cs) * 3.34)>(str); } int main(){ auto n = 573147844013817084101_cpp_int; std::cout << n << std::endl; std::cout << std::numeric_limits<decltype(n)>::digits << std::endl; auto m = 927372692193078999176_cpp_int; std::cout << m << std::endl; std::cout << std::numeric_limits<decltype(m)>::digits << std::endl; auto cpp128 = 340282366920938463463374607431768211455_cpp_int; std::cout << cpp128 << std::endl; std::cout << std::numeric_limits<decltype(cpp128)>::digits << std::endl; auto cpp256 = 115792089237316195423570985008687907853269984665640564039457584007913129639935_cpp_int; std::cout << cpp256 << std::endl; std::cout << std::numeric_limits<decltype(cpp256)>::digits << std::endl; return 0; }
[出力]
573147844013817084101 70 927372692193078999176 70 340282366920938463463374607431768211455 130 115792089237316195423570985008687907853269984665640564039457584007913129639935 260
で、ここまでやって思ったけど別にビット幅を切り詰めなくても int128_t や int256_t を使用するようにしたほうがいい気がした。
ちなみに gcc 4.8 が古いと上記のコードはコンパイルに失敗する可能性があります。
わたしの環境だと去年ビルドしたものでコンパイルエラーになりました。
最新のものだと多分大丈夫。
[boost]
- ver 1.53.0