使用rand()/(RAND_MAX +1)

IlP*_*ppo -2 c++ random

我对rand()的使用有问题:rand()/(RAND_MAX + 1.0)

我知道rand()的"简单"用法(比如rand()%100 + 1)但我不明白完整句子句子rand()/(RAND_MAX + 1.0)

Ser*_*tch 6

简单来说,rand() / (RAND_MAX + 1.0)生成一个介于0(含)和1.0(不包括)之间的浮点随机数.更准确地说(参见http://en.cppreference.com/w/cpp/numeric/random/RAND_MAX以供参考),返回的最大数量可以是RAND_MAX /(RAND_MAX + 1.0).但是,在蒙特卡罗模拟的背景下,关于这种随机数生成器有几个重点,因为RAND_MAX通常是32767:

  1. 可生成的不同随机数的数量太小:32768.通常它们运行更多的蒙特卡罗模拟 - 数百万或数十亿 - 但这种有限的随机数生成器无法运行超过32768次模拟
  2. 生成的数字太粗糙:你可以得到1/32768,2/32768,3/32768,但两者之间从来没有.
  3. 随机数生成器引擎的有限状态:在生成RAND_MAX随机数之后,实现通常开始重复相同的随机数序列.

由于rand()的上述限制,为蒙特卡罗模拟生成随机数的更好选择将是以下片段(类似于http://en.cppreference.com/w/cpp/numeric/上的示例)random/uniform_real_distribution):

#include <iostream>
#include <random>
#include <chrono>

int main()
{
    std::mt19937_64 rng;
    // initialize the random number generator with time-dependent seed
    uint64_t timeSeed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
    std::seed_seq ss{uint32_t(timeSeed & 0xffffffff), uint32_t(timeSeed>>32)};
    rng.seed(ss);
    // initialize a uniform distribution between 0 and 1
    std::uniform_real_distribution<double> unif(0, 1);
    // ready to generate random numbers
    const int nMonteCarloSimulations = 10;
    for (int i = 0; i < nMonteCarloSimulations; i++)
    {
        double currentRandomNumber = unif(rng);
        std::cout << currentRandomNumber << std::endl;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)