在 [0, n) 中生成随机数

Generate random in [0, n)

使用 C++11 的 <random> 标准 functions/classes/etc 如何生成这些范围内的随机数:

以及它们的特例:

或者可能有 <random> 的作弊 sheet 之类的文档?

Uniform Real Distribution

A uniform_real_distribution will give values in the range [a, b). We can use std::nextafter 在开放和封闭范围之间转换。

int main() {
    std::random_device rd;
    std::mt19937 mt(rd());

    // [1, 10]
    std::uniform_real_distribution<> dist_a(1, std::nextafter(10, std::numeric_limits<double>::max));

    // [1, 10)
    std::uniform_real_distribution<> dist_b(1, 10);

    // (1, 10)
    std::uniform_real_distribution<> dist_c(std::nextafter(1, std::numeric_limits<double>::max), 10);

    // (1, 10]
    std::uniform_real_distribution<> dist_d(std::nextafter(1, std::numeric_limits<double>::max), std::nextafter(10, std::numeric_limits<double>::max));

    // Random Number Generators are used like this:
    for (int i=0; i<16; ++i)
        std::cout << dist_d(mt) << "\n";
}

Uniform Int Distribution

A uniform_int_distribution 将给出 [a, b] 范围内的值。我们只需加减 1 即可在开放范围和封闭范围之间切换。

int main() {
    std::random_device rd;
    std::mt19937 mt(rd());

    // [1, 10]
    std::uniform_int_distribution<> dist_a(1, 10);    

    // [1, 10)
    std::uniform_int_distribution<> dist_b(1, 10 - 1); 

    // (1, 10)
    std::uniform_int_distribution<> dist_c(1 + 1, 10 - 1); 

    // (1, 10]
    std::uniform_int_distribution<> dist_d(1 + 1, 10);

    // Random Number Generators are used like this:
    for (int i=0; i<16; ++i)
        std::cout << dist_d(mt) << "\n";
}