6

When we are using a random number generator in C#, we can define a variable like

private Random _rndGenerator;

in a class and then call

_rndGenerator = new Random(seed);

correctly in the constructor of the class.

My question is:

What is a C++ equivalent of such a definition (i.e. an RNG in a class). I think it is not a correct approach to use

srand((unsigned int)seed);

right?

derekhh
  • 5,272
  • 11
  • 40
  • 60

2 Answers2

14

C++11 has much more powerful random-number generation facilities. Here's an example:

#include <random>
#include <functional>

std::size_t get_seed(); // whatever is the preferred way of obtaining a seed

typedef std::mt19937 engine_type; // a Mersenne twister engine
std::uniform_int_distribution<engine_type::result_type> udist(0, 200);

engine_type engine;

int main()
{
  // seed rng first:
  engine_type::result_type const seedval = get_seed();
  engine.seed(seedval);

  // bind the engine and the distribution
  auto rng = std::bind(udist, engine);

  // generate a random number
  auto random_number = rng();

  return random_number;
}

There are many ways to obtain seeds. <random> provides potential access to some hardware entropy with the std::random_device class, which you can use to seed your PRNGs.

std::size_t get_seed() {
    std::random_device entropy;
    return entropy();
}
R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
  • 2
    And if you're not using a C++11 toolset, there's [Boost.Random](http://www.boost.org/libs/random/), which the C++11 random library was loosely based on. In any case, _please_, don't use `rand`. – ildjarn Dec 05 '11 at 18:50
  • `rng_type::result_type` should probably be `engine_type::result_type` – MSalters Mar 22 '12 at 09:16
  • @MSalters oops, forgot to fix that one. Thanks. – R. Martinho Fernandes Mar 22 '12 at 09:21
  • @R.MartinhoFernandes - Would you clarify if `get_seed()` is a dummy function in your code example above, or if this is a member of the standard library? As far as I can see, `std::time(0)` is the way to go to produce a seed. – Dan Nissenbaum Mar 27 '14 at 07:38
  • @Dan it's just a placeholder for whatever the preferred method of obtaining a seed is. I added in my preferred way of getting seeds. – R. Martinho Fernandes Mar 27 '14 at 13:33
  • Note: this `get_seed()` function does not work in MinGW ([thread](http://stackoverflow.com/questions/18880654/why-do-i-get-same-sequence-for-everyrun-with-stdrandom-device-with-mingw-gcc4)) – M.M Mar 08 '15 at 13:03
1

C++ has a built-in global random number generator. If you want to seed it, then srand((unsigned int)seed) is the way to go. This isn't quite the same thing as the C# code that you showed, though. When you write:

Random _rndGenerator = new Random(seed);

You get a separate random number generator instance. So you can have multiple random number generators in your program. To my knowledge, the C++ library doesn't have such a construct, although it appears that C++ 11 does.

In short, srand((unsigned int)seed) is correct if you're using older versions of C++, or if you just want one RNG in your program. If you need multiple RNGs, then use C++ 11, or roll your own.

Jim Mischel
  • 131,090
  • 20
  • 188
  • 351