Skip to content
Why is a raven like a writing desk?

Thoughts both confusing and enlightening.

Why is a raven like a writing desk?

Thoughts both confusing and enlightening.

Rules for using <random>

elbeno, 8 April, 20153 June, 2025

These days, it’s easy to do the right thing.

Don’t do this:

  • Don’t use std::rand(). Ever.
  • Don’t use std::random_shuffle() to permute containers. (Too easy to misuse; can use std::rand() under the hood.)
  • Don’t use any kind of clock for a seed.
  • Don’t use mod (%) to get a random value into a range. It introduces bias.
  • Don’t use std::default_random_engine – it’s probably not the best choice and can vary by implementation.

Do this:

  • Use std::random_device() as a source of entropy. It should be the best randomness your OS can supply.
  • Use std::shuffle() to permute containers. Its interface doesn’t permit misuse like std::random_shuffle().
  • Use std::mt19937 (or std::mt19937_64) as an RNG engine. (Or consider PCG, but that’s not standard – yet.)
  • Seed the engine with as much seed data as it requires for its internal state (using its state_size member), otherwise you’re throwing away entropy. For std::mt19937 this is 624 32-bit values (not just a single 32-bit value). Use std::seed_seq to help with initialization.
  • RNG engines (particularly std::mt19937) can be expensive to initialize (and have large amounts of internal state), so don’t put them on the stack unnecessarily. Consider using thread_local.
  • Use std::uniform_int_distribution (and the other distributions) to get your random number into the required range. The distributions are carefully crafted to be unbiased (why you shouldn’t use %). Note that they work on closed (inclusive) ranges, not half-open ranges – otherwise the max value would be unreachable.

Wrong:

// init RNG
srand(time(NULL));

// get random number
int n = rand() % 100;

Right:

// init RNG
std::array<int, std::mt19937::state_size> seed_data;
std::random_device r;
std::generate_n(seed_data.data(), seed_data.size(), std::ref(r));
std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
std::mt19937 gen(seq);

// get random number
std::uniform_int_distribution dis(0,99);
int n = dis(gen);

Edit: Alternatively, Melissa O’Neill has produced randutils which wraps C++11 random number generation in a nice interface, and does the right thing. She knows what she’s talking about: her work on randomness is worth your time.

C++ Programming

Post navigation

Previous post
Next post

Related Posts

const_cast: A Necessary Evil

29 July, 2026

We don’t like const_cast much. It’s ugly, and can even lead to undefined behaviour. But unfortunately sometimes it’s needed. Even aside from interacting with C libraries which don’t respect const, there is at least one place in the C++ standard that requires you to use it. If you have a…

Read More

An Interesting C++ Technique

26 August, 201330 June, 2015

I recently discovered a C++ technique I haven’t seen recognized before in any books, articles, or mentioned online anywhere (search terms are difficult perhaps). For want of a better name I call it Structural Capture. Consider the following code: #include #include using namespace std; //————————————————————— struct Foo { template Foo(const…

Read More

Atomic brain to power, fingers to speed…

17 February, 200529 July, 2007

I’m not a touch typer, but I am a pretty fast (8-finger or so) typer after 20 years of keyboarding, and I don’t actually have to look at the keys much. Of course, most of the kind of typing that I do is quite different from actual written English –…

Read More

Comments (5)

  1. Alan Wolfe says:
    8 April, 2015 at 11:55 am

    Hey Ben, is std::rand() the same as the older rand(), and that’s why we should avoid it due to being low quality and offering a low range of output values?

  2. elbeno says:
    8 April, 2015 at 1:18 pm

    Yes, it’s just the old LCG.

  3. Pingback: Don’t blink, or you’ll mess up the Mersenne Twister | Backworlds
  4. Pingback: Interesting C++ Tutorials | Declan Kelly
  5. Henry says:
    8 April, 2018 at 5:55 am

    It is worthing to write an input iterator instead of using std::array so that we can avoid extra memory usage.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

©2026 Why is a raven like a writing desk? | WordPress Theme by SuperbThemes