RNG函数C ++

时间:2019-06-03 23:01:11

标签: c++ random

我试图用C ++编写一个函数,该函数每次都在0到1之间返回一个随机的float / double,每次都具有不同的值。

我尝试了srand,rand和RAND_MAX的几种不同方向,但是每次运行我的代码时,每次应更改的某些值都具有恒定值。我有一个术语x = 20 * randomnumber(),但是每次它将为x返回相同的值。无论我多久运行一次代码。这是我的功能。

double randomnumber()
{
    srand(time(NULL))
    double r1 = ((double)rand()) / RAND_MAX);

    return r1;
}

我想要做的是生成一个介于0和1之间的浮点数,以便当我乘以另一个整数时,得到一个介于0和该整数之间的值。注意:我知道有一个函数可以在0到数字之间显式地执行此操作,但是我编写的代码最好每次都乘以一个随机数。

谢谢。

2 个答案:

答案 0 :(得分:2)

代码中的一切都很好-也许您舍入了结果并且没有注意到更改。正在运行的程序将第四个十进制数字顺序更改为两倍。 从time(...)返回的time_t在我的平台上缩小为unsigned int,请检查此内容。生成一次种子就足够了-不必每次都调用randomnumber()。您写道,将结果用于蒙特卡洛模拟-生产中的蒙特卡洛模拟需要高质量的随机数-而不是rand()可能产生。

20, 25, 30

答案 1 :(得分:0)

执行此操作的最佳方法是使用C ++的随机数库, rand()

我们可以很轻松地做到这一点:

#include <random>

double randomnumber() {
    // Making rng static ensures that it stays the same
    // Between different invocations of the function
    static std::default_random_engine rng;

    std::uniform_real_distribution<double> dist(0.0, 1.0); 
    return dist(rng); 
}

这将每次生成一个新的随机数,并且每次运行该程序时都将生成相同的随机数序列。如果我运行

int main() {
    for(int i = 0; i < 10; i++) {
        std::cout << randomnumber() << '\n'; 
    }
}

那我看看

0.131538
0.45865
0.218959
0.678865
0.934693
0.519416
0.0345721
0.5297
0.00769819
0.0668422

随机初始化生成器。如果您想在每次运行程序时生成不同的随机数,则必须使用随机种子初始化生成器。生成一个很容易:

auto getRandomSeed() 
    -> std::seed_seq
{
    // This gets a source of actual, honest-to-god randomness
    std::random_device source;

    // Here, we fill an array of random data from the source
    unsigned int random_data[10];
    for(auto& elem : random_data) {
        elem = source(); 
    }

    // this creates the random seed sequence out of the random data
    return std::seed_seq(random_data + 0, random_data + 10); 
}

有了种子后,我们可以修改randomnumber()以使用随机种子创建生成器:

#include <random>

double randomnumber() {
    // Making rng static ensures that it stays the same
    // Between different invocations of the function
    static auto seed = getRandomSeed(); 
    static std::default_random_engine rng(seed);

    std::uniform_real_distribution<double> dist(0.0, 1.0); 
    return dist(rng); 
}