如何在c++中生成随机浮点数?
我想我可以用整数rand除以某个数,这足够了吗?
如何在c++中生成随机浮点数?
我想我可以用整数rand除以某个数,这足够了吗?
当前回答
调用带有两个浮点值的代码,代码可以在任何范围内工作。
float rand_FloatRange(float a, float b)
{
return ((b - a) * ((float)rand() / RAND_MAX)) + a;
}
其他回答
如果您知道您的浮点数格式是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;
}
这将比使用除法得到更好的分布。
如果您使用的是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;
调用带有两个浮点值的代码,代码可以在任何范围内工作。
float rand_FloatRange(float a, float b)
{
return ((b - a) * ((float)rand() / RAND_MAX)) + a;
}
rand()返回一个介于0和RAND_MAX之间的int值。要获得0.0到1.0之间的随机数,首先将rand()返回的int转换为浮点数,然后除以RAND_MAX。
#include <cstdint>
#include <cstdlib>
#include <ctime>
using namespace std;
/* single precision float offers 24bit worth of linear distance from 1.0f to 0.0f */
float getval() {
/* rand() has min 16bit, but we need a 24bit random number. */
uint_least32_t r = (rand() & 0xffff) + ((rand() & 0x00ff) << 16);
/* 5.9604645E-8 is (1f - 0.99999994f), 0.99999994f is the first value less than 1f. */
return (double)r * 5.9604645E-8;
}
int main()
{
srand(time(NULL));
...
我不能给出两个答案,所以这里是第二个答案。Log2随机数,很大程度上偏向于0.0f但它实际上是一个随机浮动1.0f到0.0f。
#include <cstdint>
#include <cstdlib>
#include <ctime>
using namespace std;
float getval () {
union UNION {
uint32_t i;
float f;
} r;
/* 3 because it's 0011, the first bit is the float's sign.
* Clearing the second bit eliminates values > 1.0f.
*/
r.i = (rand () & 0xffff) + ((rand () & 0x3fff) << 16);
return r.f;
}
int main ()
{
srand (time (NULL));
...