Random number generation: It might be harder than you think to write code that rivals novice-level code written in Python.

anyone could install 2013 Community Edition in a VM and look at <random>.

I probably should. I do keep a Windows 7 VM which I currently use for two tasks, very occasionally running VCDS (a.k.a. vag com) to work around a firmware bug in my car requires a poke once a year when it forgets its proper tire pressures and the more common task, applying updates to Windows 7.

Is 2013 Community Edition really the best one to install though? Isn’t there a 2015 beta? If I do play with VC++, I’d at least like a version that has the fewest idiosyncrasies and the greatest standard compliance; clang is my baseline, so I have high expectations.

Sadly, I’m not really a fan of IDEs and am happiest with a Unix terminal, so I’m not super excited about it. But I did have an irate Windows user complaining that I wasn’t handling VC++ idiosyncrasies properly in my code for the PCG library, so I probably should eventually look into that.

Non-Power-Of-Two engine treachery needs to be dealt with (frustratingly, some Standard engines are NPOT). Anything that isn't a clean number of bits needs to be discarded.

I have to think that someone must think non-power-of-two engines are a great idea, but I’m right there with you that they’re just a bag of hassle.

But technically, if the range you need is less than the range of the engine, you don’t actually need to cut down to the nearest power of two. The code I showed for bounded_rand, while not a full implementation of uniform_int_distribution, shows how.

The engine has to be run enough times to accumulate as many bits as we need for the output; more math to figure out how many bits we're getting from the engine and how many we need for the requested range. (No floating point logarithms!)

I do wish that C/C++ provided a ceiling_log2 and floor_log2 for integer types, it’s not like there aren’t efficient ways to do it (even specialized instructions in many cases), and it’s annoying for everyone to have to reinvent it when they need it.

Again, you can avoid the truncate-to-power-of-two approach for increasing the range, but doing that right is yet more hassle and probably slow (ideally, you want to work in an integer type twice as big, but if you’re crazy enough you can probably avoid it). I’ve considered writing it anyway, just because. But I think it would count as “ stashing away fractional bits of randomness”.

I write code at work all day! When I get home I just want to waste time on Reddit. :->

But I just saved you the work of writing a stateful version of uniform_int_distribution. ;-)

What I would do is use a mt19937, uniform_int_distribution, thread_local, seeded with random_device (filling the whole state; I've worked out how to do it before, it is obnoxious, but not as obnoxious as doing anything with iostreams).

I’m glad you note that it’s obnoxious, and also imply that it’s not just a couple of minutes work to do. Which raises the question, if it’s obnoxious and tedious to properly initialize mt19937 (and, from what I’ve found with cursory looking around, there are essentially no examples online showing it initialized properly), doesn’t that indicate a problem with the standard library, one that the randint proposal doesn’t really fix. (And FWIW, one that the sample randint implementation itself utterly fails to get this right either!)

BTW, is your amount-of-seeding-required hardwired in your code as a constant for mt19937, or could we swap in another engine that needs a different amount of entropy?

If you don’t want to write it, you could instead find a link to some code online that does do it properly, since that’d be pretty much just as good and you wouldn’t need to write any code. If it turns out that you can’t easily do that, doesn’t it say something? If that’s the case, don’t you need to show the world how it’s done?

/r/cpp Thread Parent