
I'm having a few problems dealing with uniform_real and uniform_01. The basic issue is that uniform_real does not always produce values between its min and its max. The problem consistently occurs when I'm using minstd_rand as my generator (one of the linear_congruential variants). For instance, if I write: template<typename RandomNumberGenerator> void foo(RandomNumberGenerator& gen) { uniform_int<int> rand_int(some_min_int, some_max_int); // Okay, some_min_int <= x <= some_max_int int x = rand_int(gen); uniform_real<double> rand_double(some_min_double, some_max_double); // Uh-oh, some_min_double <= y <= some_max_double doesn't always hold double y = rand_double(gen); } Looking at the source to uniform_real, the problem is obvious: result_type operator()(Engine& eng) { return eng() * (_max - _min) + _min; } uniform_real assumes that the engine returns a value in [0, 1], but doesn't check that. If this is correct (I hope it isn't!), the "obvious" answer is to use uniform_01<RandomNumberGenerator...> as input to uniform_real. However, uniform_01 is also broken in several ways: 1) It isn't a random distribution because its operator() does not accept an engine. Instead, the engine is embedded in the uniform_01 object. 2) uniform_01 stores the incoming random number generator by _value_, so the original generator "gen" does not advance. You can't even fake it with uniform_01<RandomNumberGenerator&>, because that creates reference-to-reference problems. Below is a small patch to make uniform_real<...> behave nicely. As for uniform_01: we should deprecate it in 1.33.0 and remove it afterwords, because it is hopelessly broken and not even included in the TR. Doug Index: uniform_real.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/random/uniform_real.hpp,v retrieving revision 1.14 diff -u -r1.14 uniform_real.hpp --- uniform_real.hpp 27 Jul 2004 03:43:32 -0000 1.14 +++ uniform_real.hpp 30 Dec 2004 22:11:33 -0000 @@ -50,7 +50,11 @@ void reset() { } template<class Engine> - result_type operator()(Engine& eng) { return eng() * (_max - _min) + _min; } + result_type operator()(Engine& eng) { + return static_cast<result_type>(eng() - eng.min()) + / (eng.max() - eng.min()) + * (_max - _min) + _min; + } #if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) template<class CharT, class Traits>