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

uniform_real_distributionでmaxを含める方法

C++

標準とBoostにあるuniform_real_distributionは、[min, max)の範囲の実数値を生成するので、maxは含みません。
これを[min, max]、つまりmaxを含む範囲にするにはどうすればいいか調べました。


どうやら、ヘッダにあるstd::nextafter()という関数を通してmax値を指定すればいいようです。
これは、浮動小数点数型において、表現可能な最小の値を取得関数です。第1引数の値から、第2引数の値の方向へ最小値だけ進めた値を返します。
uniform_real_distributionと組み合わせて、以下のように使用します。

#include <iostream>
#include <random>
#include <cmath>

int main()
{
    std::random_device seed_gen;
    std::mt19937 engine(seed_gen());

    // [-1.0, 1.0]の範囲で一様分布させる
    std::uniform_real_distribution<> dist(
        -1.0,
        std::nextafter(1.0, std::numeric_limits<double>::max())
    );

    for (int i = 0; i < 10; ++i) {
        double result = dist(engine);
        std::cout << result << std::endl;
    }
}

std::nextafter()の第2引数に渡す値は、第1引数の値より大きければいいので、2.0とかを指定してもかまいません。


参照:
std::uniform_real_distribution inclusive range - Stackoverflow
boost::math::nextafter() - Boost.Math ToolKit
rand() Considered Harmful のコメント欄 - Going Native 2013