Sampling bug in uniform_real (random)

Gabriel Corona gabriel.corona@enst-bretagne.fr
Mon Jan 19 15:30:00 GMT 2009


>probability throughout the range.  The URNG should be real-valued and
>deliver number in the range [0, 1).

I didn't see this comment.

I think (from TR1), any distribution should be usable with any kind of
URNG.

For example I should be able to do this :

std::random_device urng;
std::uniform_real_distribution<double> uniform;
std::normal_distribution<double> normal;
uniform(urng);
normal(urng)

and be able to just replace the type of the URNG
if I want to whatever URNG instead.

Doing this in the current code does not provide what is intended
because uniform_real expects a URNG in [0,1) : So if you're using
random_device or any integer base URNG with uniform_real, you get
numbers in [0,2^N-1] instead of [0,1) (on an N bits machine).

In my code I assumed a URNG providing integer values in the range
[0,2^nbits-1] (but latestest C++0x draft specifies the URNG concept
has having an unsigned integer result_type ; TR1 accepted any
arithmetic type).

One (partial) solution to have it working with other arithmetic types
as well would be something like :

__RealType __x = std::numeric_limits<
       _UniformRandomNumberGenerator>::is_integer ? 1 : 0;
return ( (__urng()-__urng.min()
        * (_M_max - _M_min)
    /( ( __x : 0.0 : 1.0 ) + (__urng.max()-__urng.min()) ))
    + _M_min;

It should work for both unsigned types and floating types (but will
overflow with signed integers).

Gabriel



More information about the Libstdc++ mailing list