如何在c++中生成随机浮点数?

我想我可以用整数rand除以某个数,这足够了吗?


当前回答

如果您知道您的浮点数格式是IEEE 754(几乎所有现代cpu,包括Intel和ARM),那么您可以使用逐位方法从一个随机整数构建一个随机浮点数。只有当你无法访问c++ 11的random或Boost时,才应该考虑这样做。随机的,两者都更好。

float rand_float()
{
    // returns a random value in the range [0.0-1.0)

    // start with a bit pattern equating to 1.0
    uint32_t pattern = 0x3f800000;

    // get 23 bits of random integer
    uint32_t random23 = 0x7fffff & (rand() << 8 ^ rand());

    // replace the mantissa, resulting in a number [1.0-2.0)
    pattern |= random23;

    // convert from int to float without undefined behavior
    assert(sizeof(float) == sizeof(uint32_t));
    char buffer[sizeof(float)];
    memcpy(buffer, &pattern, sizeof(float));
    float f;
    memcpy(&f, buffer, sizeof(float));

    return f - 1.0;
}

这将比使用除法得到更好的分布。

其他回答

rand()返回一个介于0和RAND_MAX之间的int值。要获得0.0到1.0之间的随机数,首先将rand()返回的int转换为浮点数,然后除以RAND_MAX。

调用带有两个浮点值的代码,代码可以在任何范围内工作。

float rand_FloatRange(float a, float b)
{
    return ((b - a) * ((float)rand() / RAND_MAX)) + a;
}

如果您使用的是c++而不是C,那么请记住,在技术报告1 (TR1)和c++ 0x草案中,他们在头文件中添加了用于随机数生成器的功能,我相信它与Boost是相同的。随机库和绝对更灵活和“现代”比C库函数,兰德。

该语法提供了选择生成器(如mersenne twister mt19937)然后选择分布(正态分布、伯努利分布、二项式分布等)的能力。

语法如下(无耻地借用本网站):

  #include <iostream>
  #include <random>

  ...

  std::tr1::mt19937 eng;  // a core engine class 
  std::tr1::normal_distribution<float> dist;     

  for (int i = 0; i < 10; ++i)        
      std::cout << dist(eng) << std::endl;

rand()可用于在c++中生成伪随机数。结合RAND_MAX和一点数学运算,您可以在任意选择的间隔内生成随机数。这对于学习目的和玩具程序来说是足够的。如果需要真正具有正态分布的随机数,则需要使用更高级的方法。


这将生成一个从0.0到1.0的数字。

float r = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);

这将生成一个从0.0到任意浮点数X的数字:

float r2 = static_cast <float> (rand()) / (static_cast <float> (RAND_MAX/X));

这将生成一个从任意LO到任意HI的数字:

float r3 = LO + static_cast <float> (rand()) /( static_cast <float> (RAND_MAX/(HI-LO)));

注意,如果需要真正的随机数,rand()函数通常是不够的。


在调用rand()之前,必须首先通过调用srand()来“播种”随机数生成器。这应该在程序运行期间执行一次,而不是在每次调用rand()时执行一次。通常是这样做的:

srand (static_cast <unsigned> (time(0)));

为了调用rand或srand,你必须#include <cstdlib>。

为了调用time,你必须#include <ctime>。

在一些系统上(目前想到的是带有VC的Windows), RAND_MAX小得可笑,也就是只有15位。当除以RAND_MAX时,你只生成了一个15位的尾数,而不是23位。这对您来说可能是问题,也可能不是问题,但在这种情况下,您会遗漏一些值。

哦,刚才注意到已经有关于这个问题的注释了。不管怎样,这里有一些代码可以帮你解决这个问题:

float r = (float)((rand() << 15 + rand()) & ((1 << 24) - 1)) / (1 << 24);

未经测试,但可能工作:-)