libstdc++
uniform_int_dist.h
Go to the documentation of this file.
1// Class template uniform_int_distribution -*- C++ -*-
2
3// Copyright (C) 2009-2026 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/**
26 * @file bits/uniform_int_dist.h
27 * This is an internal header file, included by other library headers.
28 * Do not attempt to use it directly. @headername{random}
29 */
30
31#ifndef _GLIBCXX_BITS_UNIFORM_INT_DIST_H
32#define _GLIBCXX_BITS_UNIFORM_INT_DIST_H
33
34#include <type_traits>
35#include <ext/numeric_traits.h>
36#if __cplusplus > 201703L
37# include <concepts>
38#endif
39#include <bits/concept_check.h> // __glibcxx_function_requires
40
41namespace std _GLIBCXX_VISIBILITY(default)
42{
43_GLIBCXX_BEGIN_NAMESPACE_VERSION
44
45#ifdef __cpp_lib_concepts
46 /// Requirements for a uniform random bit generator.
47 /**
48 * @ingroup random_distributions_uniform
49 * @headerfile random
50 * @since C++20
51 */
52 template<typename _Gen>
54 = invocable<_Gen&> && unsigned_integral<invoke_result_t<_Gen&>>
55 && requires
56 {
57 { _Gen::min() } -> same_as<invoke_result_t<_Gen&>>;
58 { _Gen::max() } -> same_as<invoke_result_t<_Gen&>>;
59 requires bool_constant<(_Gen::min() < _Gen::max())>::value;
60 };
61#endif
62
63 /// @cond undocumented
64 namespace __detail
65 {
66 // Determine whether number is a power of two.
67 // This is true for zero, which is OK because we want _Power_of_2(n+1)
68 // to be true if n==numeric_limits<_Tp>::max() and so n+1 wraps around.
69 template<typename _Tp>
70 constexpr bool
71 _Power_of_2(_Tp __x)
72 {
73 return ((__x - 1) & __x) == 0;
74 }
75
76 template<int __s,
77 int __which = ((__s <= __CHAR_BIT__ * sizeof (int))
78 + (__s <= __CHAR_BIT__ * sizeof (long))
79 + (__s <= __CHAR_BIT__ * sizeof (long long))
80 /* assume long long no bigger than __int128 */
81 + (__s <= 128))>
82 struct _Select_uint_least_t
83 {
84 static_assert(__which < 0, /* needs to be dependent */
85 "sorry, would be too much trouble for a slow result");
86 };
87
88 template<int __s>
89 struct _Select_uint_least_t<__s, 4>
90 { using type = unsigned int; };
91
92 template<int __s>
93 struct _Select_uint_least_t<__s, 3>
94 { using type = unsigned long; };
95
96 template<int __s>
97 struct _Select_uint_least_t<__s, 2>
98 { using type = unsigned long long; };
99
100#if __SIZEOF_INT128__ > __SIZEOF_LONG_LONG__
101 template<int __s>
102 struct _Select_uint_least_t<__s, 1>
103 { __extension__ using type = unsigned __int128; };
104#elif __has_builtin(__builtin_add_overflow) \
105 && __has_builtin(__builtin_sub_overflow) \
106 && defined __UINT64_TYPE__
107 template<int __s>
108 struct _Select_uint_least_t<__s, 1>; // Defined in bits/random.h
109#endif
110 }
111 /// @endcond
112
113 /**
114 * @brief Uniform discrete distribution for random numbers.
115 * A discrete random distribution on the range @f$[min, max]@f$ with equal
116 * probability throughout the range.
117 *
118 * @ingroup random_distributions_uniform
119 * @headerfile random
120 * @since C++11
121 */
122 template<typename _IntType = int>
124 {
126 "template argument must be an integral type");
127
128 public:
129 /** The type of the range of the distribution. */
130 typedef _IntType result_type;
131 /** Parameter type. */
132 struct param_type
133 {
134 typedef uniform_int_distribution<_IntType> distribution_type;
135
136 param_type() : param_type(0) { }
137
138 explicit
139 param_type(_IntType __a,
140 _IntType __b = __gnu_cxx::__int_traits<_IntType>::__max)
141 : _M_a(__a), _M_b(__b)
142 {
143 __glibcxx_assert(_M_a <= _M_b);
144 }
145
147 a() const
148 { return _M_a; }
149
151 b() const
152 { return _M_b; }
153
154 friend bool
155 operator==(const param_type& __p1, const param_type& __p2)
156 { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
157
158 friend bool
159 operator!=(const param_type& __p1, const param_type& __p2)
160 { return !(__p1 == __p2); }
161
162 private:
163 _IntType _M_a;
164 _IntType _M_b;
165 };
166
167 public:
168 /**
169 * @brief Constructs a uniform distribution object.
170 */
172
173 /**
174 * @brief Constructs a uniform distribution object.
175 */
176 explicit
178 _IntType __b
179 = __gnu_cxx::__int_traits<_IntType>::__max)
180 : _M_param(__a, __b)
181 { }
182
183 explicit
184 uniform_int_distribution(const param_type& __p)
185 : _M_param(__p)
186 { }
187
188 /**
189 * @brief Resets the distribution state.
190 *
191 * Does nothing for the uniform integer distribution.
192 */
193 void
194 reset() { }
195
196 result_type
197 a() const
198 { return _M_param.a(); }
199
200 result_type
201 b() const
202 { return _M_param.b(); }
203
204 /**
205 * @brief Returns the parameter set of the distribution.
206 */
207 param_type
208 param() const
209 { return _M_param; }
210
211 /**
212 * @brief Sets the parameter set of the distribution.
213 * @param __param The new parameter set of the distribution.
214 */
215 void
216 param(const param_type& __param)
217 { _M_param = __param; }
218
219 /**
220 * @brief Returns the inclusive lower bound of the distribution range.
221 */
222 result_type
223 min() const
224 { return this->a(); }
225
226 /**
227 * @brief Returns the inclusive upper bound of the distribution range.
228 */
229 result_type
230 max() const
231 { return this->b(); }
232
233 /**
234 * @brief Generating functions.
235 */
236 template<typename _UniformRandomBitGenerator>
237 result_type
238 operator()(_UniformRandomBitGenerator& __urng)
239 { return this->operator()(__urng, _M_param); }
240
241 template<typename _UniformRandomBitGenerator>
242 result_type
243 operator()(_UniformRandomBitGenerator& __urng,
244 const param_type& __p);
245
246 template<typename _ForwardIterator,
247 typename _UniformRandomBitGenerator>
248 void
249 __generate(_ForwardIterator __f, _ForwardIterator __t,
250 _UniformRandomBitGenerator& __urng)
251 { this->__generate(__f, __t, __urng, _M_param); }
252
253 template<typename _ForwardIterator,
254 typename _UniformRandomBitGenerator>
255 void
256 __generate(_ForwardIterator __f, _ForwardIterator __t,
257 _UniformRandomBitGenerator& __urng,
258 const param_type& __p)
259 { this->__generate_impl(__f, __t, __urng, __p); }
260
261 template<typename _UniformRandomBitGenerator>
262 void
263 __generate(result_type* __f, result_type* __t,
264 _UniformRandomBitGenerator& __urng,
265 const param_type& __p)
266 { this->__generate_impl(__f, __t, __urng, __p); }
267
268 /**
269 * @brief Return true if two uniform integer distributions have
270 * the same parameters.
271 */
272 friend bool
274 const uniform_int_distribution& __d2)
275 { return __d1._M_param == __d2._M_param; }
276
277 private:
278 template<typename _ForwardIterator,
279 typename _UniformRandomBitGenerator>
280 void
281 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
282 _UniformRandomBitGenerator& __urng,
283 const param_type& __p);
284
285 param_type _M_param;
286
287 // Lemire's nearly divisionless algorithm.
288 // Returns an unbiased random number from __g downscaled to [0,__range)
289 // using an unsigned type _Wp twice as wide as unsigned type _Up.
290 template<size_t _Bits, typename _Urbg>
291 static typename __detail::_Select_uint_least_t<_Bits>::type
292 _S_nd(_Urbg& __g, typename __detail::_Select_uint_least_t<_Bits>::type __range)
293 {
294 using _Up = typename __detail::_Select_uint_least_t<_Bits>::type;
295 using _Wp = typename __detail::_Select_uint_least_t<2 * _Bits>::type;
296 using _Up_traits = __gnu_cxx::__int_traits<_Up>;
297
298 constexpr auto __min = _Urbg::min();
299 constexpr _Up __mask = (_Bits < _Up_traits::__digits)
300 ? (_Up(1) << _Bits) - 1 : ~_Up(0);
301
302 // reference: Fast Random Integer Generation in an Interval
303 // ACM Transactions on Modeling and Computer Simulation 29 (1), 2019
304 // https://arxiv.org/abs/1805.10941
305 _Wp __product = _Wp(__g() - __min) * _Wp(__range);
306 _Up __low = _Up(__product) & __mask;
307 if (__low < __range)
308 {
309 const _Up __threshold = -__range % __range;
310 while (__low < __threshold)
311 {
312 __product = _Wp(__g() - __min) * _Wp(__range);
313 __low = _Up(__product) & __mask;
314
315 // The algorithm is modified to alternate between rejecting
316 // from the beginning and end of the range. This guarantees
317 // that we stop for non-uniform engines that always result
318 // in values below the __threshold.
319 const _Up __back_threshold = __mask - __threshold;
320 if (__low <= __back_threshold)
321 break;
322
323 __product = _Wp(__g() - __min) * _Wp(__range);
324 __low = _Up(__product) & __mask;
325 }
326 }
327 return _Up(__product >> _Bits) & __mask;
328 }
329 };
330
331 template<typename _IntType>
332 template<typename _UniformRandomBitGenerator>
335 operator()(_UniformRandomBitGenerator& __urng,
336 const param_type& __param)
337 {
338 typedef decltype(__urng()) _Gresult_type;
339 typedef typename make_unsigned<result_type>::type __utype;
340 typedef typename common_type<_Gresult_type, __utype>::type __uctype;
341
342 constexpr __uctype __urngmin = _UniformRandomBitGenerator::min();
343 constexpr __uctype __urngmax = _UniformRandomBitGenerator::max();
344 static_assert( __urngmin < __urngmax,
345 "Uniform random bit generator must define min() < max()");
346 constexpr __uctype __urngrange = __urngmax - __urngmin;
347
348 const __uctype __urange
349 = __uctype(__param.b()) - __uctype(__param.a());
350
351 __uctype __ret;
352 if (__urngrange > __urange)
353 {
354 // downscaling
355
356 const __uctype __uerange = __urange + 1; // __urange can be zero
357
358#pragma GCC diagnostic push
359#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
360#if __has_builtin(__builtin_popcountg)
361 constexpr auto __bits = __builtin_popcountg(__urngrange);
362 if constexpr (__detail::_Power_of_2(__urngrange + 1) && __bits <= 32)
363 {
364 // __urng produces values that use no more than 32-bits,
365 // so 64-bit integer is sufficient to downscale to desired range.
366 __UINT32_TYPE__ __u32erange = __uerange;
367 __ret = _S_nd<__bits>(__urng, __u32erange);
368 }
369# if __SIZEOF_INT128__
370 else if constexpr (__detail::_Power_of_2(__urngrange + 1) && __bits <= 64)
371 {
372 // __urng produces values that use no more than 64-bits,
373 // so 128-bit integer is sufficient to downscale to desired range.
374 __UINT64_TYPE__ __u64erange = __uerange;
375 __ret = _S_nd<__bits>(__urng, __u64erange);
376 }
377# endif
378 else
379#endif
380 {
381 // fallback case (2 divisions)
382 const __uctype __scaling = __urngrange / __uerange;
383 const __uctype __past = __uerange * __scaling;
384 do
385 __ret = __uctype(__urng()) - __urngmin;
386 while (__ret >= __past);
387 __ret /= __scaling;
388 }
389#pragma GCC diagnostic pop
390 }
391 else if (__urngrange < __urange)
392 {
393 // upscaling
394 /*
395 Note that every value in [0, urange]
396 can be written uniquely as
397
398 (urngrange + 1) * high + low
399
400 where
401
402 high in [0, urange / (urngrange + 1)]
403
404 and
405
406 low in [0, urngrange].
407 */
408 __uctype __tmp; // wraparound control
409 do
410 {
411 const __uctype __uerngrange = __urngrange + 1;
412 __tmp = (__uerngrange * operator()
413 (__urng, param_type(0, __urange / __uerngrange)));
414 __ret = __tmp + (__uctype(__urng()) - __urngmin);
415 }
416 while (__ret > __urange || __ret < __tmp);
417 }
418 else
419 __ret = __uctype(__urng()) - __urngmin;
420
421 return __ret + __param.a();
422 }
423
424
425 template<typename _IntType>
426 template<typename _ForwardIterator,
427 typename _UniformRandomBitGenerator>
428 void
430 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
431 _UniformRandomBitGenerator& __urng,
432 const param_type& __param)
433 {
434 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
435 typedef decltype(__urng()) _Gresult_type;
436 typedef typename make_unsigned<result_type>::type __utype;
437 typedef typename common_type<_Gresult_type, __utype>::type __uctype;
438
439 static_assert( __urng.min() < __urng.max(),
440 "Uniform random bit generator must define min() < max()");
441
442 constexpr __uctype __urngmin = __urng.min();
443 constexpr __uctype __urngmax = __urng.max();
444 constexpr __uctype __urngrange = __urngmax - __urngmin;
445 const __uctype __urange
446 = __uctype(__param.b()) - __uctype(__param.a());
447
448 __uctype __ret;
449
450 if (__urngrange > __urange)
451 {
452 if (__detail::_Power_of_2(__urngrange + 1)
453 && __detail::_Power_of_2(__urange + 1))
454 {
455 while (__f != __t)
456 {
457 __ret = __uctype(__urng()) - __urngmin;
458 *__f++ = (__ret & __urange) + __param.a();
459 }
460 }
461 else
462 {
463 // downscaling
464 const __uctype __uerange = __urange + 1; // __urange can be zero
465 const __uctype __scaling = __urngrange / __uerange;
466 const __uctype __past = __uerange * __scaling;
467 while (__f != __t)
468 {
469 do
470 __ret = __uctype(__urng()) - __urngmin;
471 while (__ret >= __past);
472 *__f++ = __ret / __scaling + __param.a();
473 }
474 }
475 }
476 else if (__urngrange < __urange)
477 {
478 // upscaling
479 /*
480 Note that every value in [0, urange]
481 can be written uniquely as
482
483 (urngrange + 1) * high + low
484
485 where
486
487 high in [0, urange / (urngrange + 1)]
488
489 and
490
491 low in [0, urngrange].
492 */
493 __uctype __tmp; // wraparound control
494 while (__f != __t)
495 {
496 do
497 {
498 constexpr __uctype __uerngrange = __urngrange + 1;
499 __tmp = (__uerngrange * operator()
500 (__urng, param_type(0, __urange / __uerngrange)));
501 __ret = __tmp + (__uctype(__urng()) - __urngmin);
502 }
503 while (__ret > __urange || __ret < __tmp);
504 *__f++ = __ret;
505 }
506 }
507 else
508 while (__f != __t)
509 *__f++ = __uctype(__urng()) - __urngmin + __param.a();
510 }
511
512 // operator!= and operator<< and operator>> are defined in <bits/random.h>
513
514_GLIBCXX_END_NAMESPACE_VERSION
515} // namespace std
516
517#endif
ISO C++ entities toplevel namespace is std.
Implementation details not part of the namespace std interface.
__numeric_traits_integer< _Tp > __int_traits
Convenience alias for __numeric_traits<integer-type>.
is_integral
Definition type_traits:565
common_type
Definition type_traits:2601
Uniform discrete distribution for random numbers. A discrete random distribution on the range with e...
void reset()
Resets the distribution state.
uniform_int_distribution()
Constructs a uniform distribution object.
void param(const param_type &__param)
Sets the parameter set of the distribution.
result_type min() const
Returns the inclusive lower bound of the distribution range.
friend bool operator==(const uniform_int_distribution &__d1, const uniform_int_distribution &__d2)
Return true if two uniform integer distributions have the same parameters.
result_type max() const
Returns the inclusive upper bound of the distribution range.
result_type operator()(_UniformRandomBitGenerator &__urng)
Generating functions.
uniform_int_distribution(_IntType __a, _IntType __b=__gnu_cxx::__int_traits< _IntType >::__max)
Constructs a uniform distribution object.
param_type param() const
Returns the parameter set of the distribution.
[concept.same], concept same_as
Definition concepts:65
[concept.invocable], concept invocable
Definition concepts:383
Requirements for a uniform random bit generator.