**Section:** 29.6.1.3 [rand.req.urng] **Status:** NAD
**Submitter:** Stephan T. Lavavej **Opened:** 2013-09-21 **Last modified:** 2016-02-10

**Priority: **Not Prioritized

**View all other** issues in [rand.req.urng].

**View all issues with** NAD status.

**Discussion:**

29.6.1.3 [rand.req.urng] allows URNGs with non-power-of-two (NPOT) ranges, like `[0, 1729]`. This is unnecessarily permissive
(I cannot imagine a realistic source of randomness that would generate such a range) and has real costs for implementers, as
`uniform_int_distribution` must be prepared to accept such URNGs. The most efficient way to accumulate randomness is to
concatenate random bits, so NPOT randomness is not just useless, it is actively harmful (to avoid bias, if a URNG generates a
random number outside of a power-of-two range, the number must be discarded).

Forbidding NPOT URNGs wouldn't affect users, and would simplify Standard Library implementations. It would be nice to require
`min()` to be `0`, but this is not necessary; it is simple for implementations to say `g() - G::min()` and
this will optimize away if `min()` is `0`. (It is vaguely plausible for a URNG to have a nonzero minimum; I can
imagine something that simply masks off low-order bits without shifting the rest downwards.) What is important is for the entire
range to have a power-of-two width; `[1729, 1984]` is acceptable as its size is 256.

*[2013-10-12: Howard presents a counterexample]*

Consider:

#include <random> #include <string> #include <iostream> template <class Int> bool is_power_2m1(Int i) { return (i & (i + 1)) == 0; } template <class URNG> void test(const std::string& urng) { using namespace std; typename URNG::result_type rng = URNG::max() - URNG::min(); if (!is_power_2m1(rng)) { cout << hex; cout << urng << " : min = " << URNG::min() << ", max = " << URNG::max() << ", max-min = " << rng << '\n'; } }; int main() { using namespace std; test<minstd_rand0>("minstd_rand0"); test<minstd_rand>("minstd_rand"); test<mt19937>("mt19937"); test<mt19937_64>("mt19937_64"); test<ranlux24_base>("ranlux24_base"); test<ranlux48_base>("ranlux48_base"); test<ranlux24>("ranlux24"); test<ranlux48>("ranlux48"); test<knuth_b>("knuth_b"); }

Which for me outputs:

minstd_rand0 : min = 1, max = 7ffffffe, max-min = 7ffffffd minstd_rand : min = 1, max = 7ffffffe, max-min = 7ffffffd knuth_b : min = 1, max = 7ffffffe, max-min = 7ffffffd

We do not want to outlaw these three URNG's, and the proposed wording would do that.

*[Issaquah 2014-02-10: Moved to NAD]*

STL withdraws the issue, non-power-of-2 URNGs are used in the field, it is too late to consider removing them.

**Proposed resolution:**

This wording is relative to N3691.

Add a new paragraph at the end of 29.6.1.3 [rand.req.urng] as indicated:

-3- The following relation shall hold:

`G::min() < G::max()`.-?-

`G::max() - G::min()`shall be 2^{n}- 1 for some`n > 0`.