The C++11 standard library contains a decent framework and a couple of serviceable generators, which is perfectly sufficient for homework assignments and off-the-cuff use.
However, for production-grade code you should know exactly what the specific properties of the various generators are before you use them, since all of them have their caveats. Also, none of them passes standard tests for PRNGs like TestU01, except for the ranlux generators if used with a generous luxury factor.
If you want solid, repeatable results then you have to bring your own generator.
If you want portability then you have to bring your own generator.
If you can live with restricted portability then you can use boost, or the C++11 framework in conjunction with your own generator(s).
More detail - including code for a simple yet fast generator of excellent quality and copious links - can be found in my answers to similar topics:
For professional uniform floating-point deviates there are two more issues to consider:
- open vs. half-open vs. closed range, i.e. (0,1), [0, 1) or [0,1]
- method of conversion from integral to floating-point (precision, speed)
Both are actually two sides of the same coin, as the method of conversion takes care of the inclusion/exclusion of 0 and 1. Here are three different methods for the half-open interval:
// exact values computed with bc
#define POW2_M32 2.3283064365386962890625e-010
#define POW2_M64 5.421010862427522170037264004349e-020
double random_double_a ()
{
double lo = random_uint32() * POW2_M64;
return lo + random_uint32() * POW2_M32;
}
double random_double_b ()
{
return random_uint64() * POW2_M64;
}
double random_double_c ()
{
return int64_t(random_uint64()) * POW2_M64 + 0.5;
}
(random_uint32()
and random_uint64()
are placeholders for your actual functions and would normally be passed as template parameters)
Method a demonstrates how to create a uniform deviate that is not biassed by excess precision for lower values; the code for 64-bit is not shown because it is simpler and just involves masking off 11 bits. The distribution is uniform for all functions but without this trick there would be more different values in the area closer to 0 than elsewhere (finer grid spacing due to the varying ulp).
Method c shows how to get a uniform deviate faster on certain popular platforms where the FPU knows only a signed 64-bit integral type. What you see most often is method b but there the compiler has to generate lots of extra code under the hood to preserve the unsigned semantics.
Mix and match these principles to create your own tailored solution.
All this is explained in Jürgen Doornik's excellent paper Conversion of High-Period Random Numbers to Floating Point.