読者です 読者をやめる 読者になる 読者になる

乱数分布と8ビット整数

C++

C++標準ライブラリの乱数分布クラスは、テンプレートパラメータとして、IntTypeUIntTypeRealTypeのいずれかをとります。

整数型IntTypeUIntTypeとしては、std::is_integral特性を満たす整数型ではなく、以下の整数型のみが許可されています。

  • short
  • int
  • long
  • long long
  • unsigned short
  • unsigned int
  • unsigned long
  • unsigned long long

この中には、charがありません。

そのため、8ビットの固定精度整数型であるstd::int8_tstd::uint8_tは、分布クラスが生成する整数型として使えません。

だいたいの実装では、テンプレートパラメータの型の制限はstd::is_integralで行われているので、たとえばGCC 4.8(libstdc++)やClang 3.4(libc++)だと、以下のコードは通ります。

#include <iostream>
#include <random>
#include <cstdint>

int main()
{
    std::random_device seed_gen;
    std::mt19937 engine(seed_gen());
   
    std::uniform_int_distribution<std::uint8_t> dist {
        0,
        std::numeric_limits<std::uint8_t>::max()
    };
   
    for (int i = 0; i < 10; ++i) {
        int result = dist(engine);
        std::cout << result << std::endl;
    }
}

出力例:

231
206
155
107
47
226
242
143
119
34

なので、とくに意識せず8ビット整数を分布クラスで作っていた方は、「C++11の規格上では、許可されていない」というのを理解した上で使ってください。

ちなみに、Boost.Randomにはとくに制限がありません。

参照

charは許可していいだろう、という問題報告はすでにされていますが、C++14に入る予定は今のところないようです。

LWG 2326. uniform_int_distribution<unsigned char> should be permitted