bordeo - 1 year ago 58

Python Question

So this question is sort of one of translation. I am new to C++, and was looking through the class documentation. However, it looks like finding the answer to my question is a bit hard via the documentation.

I have code for generating a random number between 0 and 1 in C++: (obtained from here, since the rand() function solution for floats is integer based)

`#include <random>`

#include <iostream>

int main()

{

std::random_device rd;

std::mt19937 gen(rd());

std::uniform_real_distribution<> dis(0, 1); //corrected from 1,2

for (int n = 0; n < 10; ++n) {

std::cout << dis(gen) << ' ';

}

std::cout << '\n';

}

Next, I would like to create a class or struct or something (not really an OOP guy) that has an API like:

`float x = my_RandomNumberGenerator.next();`

In python, I might write something like:

`class my_RNG():`

def __init__(self):

self.rd = (the random device object I initialize in c code)

self.gen = (the mersenne_twister engine object)(rd)

self.distribution = (the uniform real distribution object)

def next():

return self.distribution(self.gen)

my_randomNumberGenerator = my_RNG()

print(my_randomNumberGenerator.next())

How would I implement this in C++?

`#include <iostream>`

#include <random>

class MyRNG

{

public:

float next(void);

private:

std::random_device randomDevice;

std::mt19937_64 randomGenerator;

std::uniform_real_distribution distribution;

MyRNG(float range_lower,float range_upper);

};

MyRNG::MyRNG(float range_lower, float range_upper)

{

randomGenerator = std::mersenne_twister_engine(randomDevice);

distribution = std::uniform_real_distribution<> distribution(range_lower,range_upper);

}

MyRNG::next(void)

{

return distribution(randomGenerator);

}

int main() {

MyRNG my_rng = MyRNG(0,1);

std::cout << my_rng.next() << std::endl;

return 0;

}

Answer Source

Seems like you just need some form of probability generation class, see below for a basic implementation which meets your question requirements:

```
template<class Ty = double,
class = std::enable_if_t<std::is_floating_point<Ty>::value>
> class random_probability_generator {
public:
// default constructor uses single random_device for seeding
random_probability_generator()
: mt_eng{std::random_device{}()}, prob_dist(0.0, 1.0) {}
// ... other constructors with custom seeds if necessary
Ty next() { return dist(mt_eng); }
// ... other methods if necessary
private:
std::mt19937 mt_eng;
std::uniform_real_distribution<Ty> prob_dist;
};
```

Then you can use this simply via:

```
random_probability_generator<> pgen;
double p = pgen.next(); // double in range [0.0, 1.0]
```

Or if you want random `float`

s instead (as part of your question seems to imply):

```
random_probability_generator<float> pgen;
float p = pgen.next(); // float in range [0.0f, 1.0f]
```

Also, to address why the class you posted isn't compiling, the error in your class is that you try to initialise a `std::mt19937_64`

type object (`randomGenerator`

) with a `std::mersenne_twister_engine`

instance but they are fundamentally different types. Instead you would need to do

```
randomGenerator = std::mt19937_64(randomDevice());
```

in `MyRNG`

constructor, or construct via initialisation list as I have done in the example above.