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

Exploring Pascal’s Triangle

19 August, 2007

Pascal’s Triangle (henceforth known as PT). You know – that thing you learned in maths. The Wikipedia entry, like most mathematical Wikipedia entries, reads (if your mathematical background is anything like mine) like “here’s a few things you might vaguely remember from school, oh and of course gleep = glorp”….

Read More

A problem with C++ lambdas?

18 February, 201530 June, 2015

C++ lambdas are wonderful for all sorts of reasons (especially with their C++14-and-beyond power). But I’ve run into a problem that I can’t think of a good way around yet. If you’re up to date with C++, of course you know that rvalue references and move semantics are a major…

Read More

fighting the code

25 March, 200729 July, 2007

Why doesn’t automake/autoconf properly recognise the way to use Flex/Bison with C++ scanner/parser generation? I use a .ll file and it thinks the output is going to be a .c instead of a .cc. Likewise I use a .yy file and it screws up the includes in my bison output…

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