I am trying to generate randoms within a range. I have multiple objects in multiple threads that would be calling this function, the function is in a singleton class so there is only one object that is called. But I noticed that my random numbers are closer to the middle of the range and by consequence, to each other for the first 200 calls, then they start to slowly disperse over the given range.
std::uniform_real_distribution<double> dis
as a class variable but i kept getting errors that uniform_real_distribution
is not a member of std::
why is that ?std::shared_ptr< std::uniform_real_distribution<double> > _uniform_distribution
as a class variable, and still got errors.double getRandom(Object* foo){
std::random_device rnd;
std::mt19937 gen(rnd());
std::uniform_real_distribution<double> dis(0, foo->limit);
double random = dis(gen);
return random;
}
You should seed a random number generator only once. Other than that, your getRandom
function is correct. As for how to use all this in a class context, here's how you could do it:
#include <random>
class RNG
{
public:
RNG::RNG() : gen(std::random_device()()) {} // Seeds the mt19937.
double getRandom(Object* foo){
std::uniform_real_distribution<double> dis(0, foo->limit);
double random = dis(gen);
return random;
}
private:
std::mt19937 gen;
};
So at the the start of the program, you instantiate one RNG
, and the mt19937
will be seeded once. Then you just call getRandom
on that same RNG
whenever you need a random number.
If you want to make your distribution a member variable then you have to create new parameters on each invocation:
#include <random>
#include <iostream>
class Object
{
public:
double limit = 100.0;
};
class MyRandomGen
{
// typedef this for readability
typedef typename std::uniform_real_distribution<double>::param_type param_type;
std::mt19937 gen;
std::uniform_real_distribution<double> dis;
public:
MyRandomGen(): gen(std::random_device()()) {} // seed only once
double getRandom(Object* foo)
{
param_type range {0, foo->limit}; // new distribution parameters
return dis(gen, range);
}
};
int main()
{
Object o;
MyRandomGen gen;
for(auto i = 0; i < 10; ++i)
std::cout << gen.getRandom(&o) << '\n';
}
Output:
48.4072
11.9905
39.0123
49.2113
69.3635
0.369986
19.9654
42.4251
92.9024
29.7522
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With