...one of the most highly
regarded and expertly designed C++ library projects in the
world.

— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards

boost::uniform_smallint

// In header: <boost/random/uniform_smallint.hpp> template<typename IntType = int> class uniform_smallint { public: // types typedef IntType input_type; typedef IntType result_type; // construct/copy/destruct uniform_smallint(IntType = 0, IntType = 9); // public member functions result_type min() const; result_type max() const; void reset(); template<typename Engine> result_type operator()(Engine &); };

The distribution function uniform_smallint models a random distribution . On each invocation, it returns a random integer value uniformly distributed in the set of integer numbers {min, min+1, min+2, ..., max}. It assumes that the desired range (max-min+1) is small compared to the range of the underlying source of random numbers and thus makes no attempt to limit quantization errors.

Let r_{out}=(max-min+1) the desired range of integer numbers, and let r_{base} be the range of the underlying source of random numbers. Then, for the uniform distribution, the theoretical probability for any number i in the range r_{out} will be p_{out}(i) = 1/r_{out}. Likewise, assume a uniform distribution on r_{base} for the underlying source of random numbers, i.e. p_{base}(i) = 1/r_{base}. Let p_{out_s}(i) denote the random distribution generated by `uniform_smallint`

. Then the sum over all i in r_{out} of (p_{out_s}(i)/p_{out}(i) - 1)^{2} shall not exceed r_{out}/r_{base}^{2} (r_{base} mod r_{out})(r_{out} - r_{base} mod r_{out}).

The template parameter IntType shall denote an integer-like value type.

Note: The property above is the square sum of the relative differences in probabilities between the desired uniform distribution p_{out}(i) and the generated distribution p_{out_s}(i). The property can be fulfilled with the calculation (base_rng mod r_{out}), as follows: Let r = r_{base} mod r_{out}. The base distribution on r_{base} is folded onto the range r_{out}. The numbers i < r have assigned (r_{base} div r_{out})+1 numbers of the base distribution, the rest has only (r_{base} div r_{out}). Therefore, p_{out_s}(i) = ((r_{base} div r_{out})+1) / r_{base} for i < r and p_{out_s}(i) = (r_{base} div r_{out})/r_{base} otherwise. Substituting this in the above sum formula leads to the desired result.

Note: The upper bound for (r_{base} mod r_{out}) (r_{out} - r_{base} mod r_{out}) is r_{out}^{2}/4. Regarding the upper bound for the square sum of the relative quantization error of r_{out}^{3}/(4*r_{base}^{2}), it seems wise to either choose r_{base} so that r_{base} > 10*r_{out}^{2} or ensure that r_{base} is divisible by r_{out}.