如何在c++中生成随机浮点数?
我想我可以用整数rand除以某个数,这足够了吗?
如何在c++中生成随机浮点数?
我想我可以用整数rand除以某个数,这足够了吗?
当前回答
#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));
...
其他回答
对于c++,它可以在dist变量指定的范围内生成实浮点数
#include <random> //If it doesnt work then use #include <tr1/random>
#include <iostream>
using namespace std;
typedef std::tr1::ranlux64_base_01 Myeng;
typedef std::tr1::normal_distribution<double> Mydist;
int main() {
Myeng eng;
eng.seed((unsigned int) time(NULL)); //initializing generator to January 1, 1970);
Mydist dist(1,10);
dist.reset(); // discard any cached values
for (int i = 0; i < 10; i++)
{
std::cout << "a random value == " << (int)dist(eng) << std::endl;
}
return (0);
}
调用带有两个浮点值的代码,代码可以在任何范围内工作。
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++11附带的<random>头文件。 要获得随机浮点数,可以使用std::uniform_real_distribution<>。
你可以使用一个函数来生成数字,如果你不希望数字总是相同的,那就将引擎和分布设置为静态。 例子:
float get_random()
{
static std::default_random_engine e;
static std::uniform_real_distribution<> dis(0, 1); // rage 0 - 1
return dis(e);
}
理想的做法是将浮动对象放置在std::vector:这样的容器中:
int main()
{
std::vector<float> nums;
for (int i{}; i != 5; ++i) // Generate 5 random floats
nums.emplace_back(get_random());
for (const auto& i : nums) std::cout << i << " ";
}
示例输出:
0.0518757 0.969106 0.0985112 0.0895674 0.895542
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>。