2

I have a function that calls srand and rand like this:

void foo() { int seed = some_operation(); std::srand(seed); int value = std::rand(); // Do something with random value } 

However, I don't want to change the global state of rand. Whats the easiest way to get a random number then?

Requirements:

  • random number must be deterministic based on seed
  • C++11 is fine
  • foo should be thread safe
  • the global state of rand should not be modified

Edit:

There is a stackoverflow question asking how to generate random numbers. The accepted answer however shows how to generate truly unique random numbers, using a slow std::random_device. I just needed a simple generator using a fixed seed instead.

2

3 Answers 3

4

C++11 is fine

Then use the new pseudorandom number library:

#include <random> int foo() { int seed = some_operation(); std::minstd_rand rand(seed); int value = rand(); // Do something with random value } 

minstd_rand is a simple linear congruential engine, similar to that typically used by std::rand(), but with its state encapsulated in a class. Other engines are available, if you need a higher quality pseudorandom sequence. The Mersenne Twister, std::mt19937, is usually a good choice if you don't have specific requirements.

Sign up to request clarification or add additional context in comments.

2 Comments

@Brahim: To protect what? The engine is a local variable, so can only be accessed by the thread that's calling the function.
You are right. I just thought that the library functon's thread-safety may be undefined.
2

<random> defines a number of PRNG classes that you can use, which do not use global states.

For example, using a default Mersenne Twister, std::mt19937:

#include <iostream> #include <random> int main() { int seed = 1234; std::mt19937 rng(seed); std::cout << "Random number: " << rng() << std::endl; } 

Comments

1

One approach is to provide your own implementation, with its own seed data. A template for doing that is provided in the manpage for rand().

static unsigned long next = 1; /* RAND_MAX assumed to be 32767 */ int myrand(void) { next = next * 1103515245 + 12345; return((unsigned)(next/65536) % 32768); } void mysrand(unsigned seed) { next = seed; } 

3 Comments

He asked for a solution with no global state, and you post an answer with global state.
@DanielKO: Actually, he said he didn't want to change the global state of rand(), which this does not. I get your point, however, and was kind of expecting that someone could modify this to manage the state in a way that suited their purposes -- for example if they wanted one seed per thread, that would require custom logic which isn't addressed in any of the answers.
Note: The above code was copied verbatim from the man page. It is really only an example of how you might generate a predictable random number sequence in a very portable way (and with custom state data). Approaches using <random> are likely better if you are targeting C++11 specifically. The code, as written, is not thread-safe. To achieve thread-safety you need to manage the state variable next in a way that matches your thread safety strategy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.