Поскольку generator()
является равномерным распределением по [generator.min(), generator.max()]
, generator() % n
не является равномерным распределением по [0, n)
(если generator.max()
не является точным кратным n
, предполагая generator.min () == 0).
Давайте рассмотрим пример: min() == 0
, max() == 65'535
и n == 7
.
gen()
будут давать числа в диапазоне [0, 65'535]
и в этом диапазонеявляются:
9'363
числа, такие как gen() % 7 == 0
9'363
числа, такие как gen() % 7 == 1
9'362
числа, такие как gen() % 7 == 2
9'362
чисел, таких как gen() % 7 == 3
9'362
чисел, таких как gen() % 7 == 4
9'362
чисел, таких как gen() % 7 == 5
9'362
числа такие, что gen() % 7 == 6
Если вам интересно, откуда я взял эти числа, подумайте об этом так: 65'534
является точным кратным 7
(65'534 = 7 * 9'362
). Это означает, что в [0, 65'533]
есть ровно 9'362
числа, которые сопоставляются с каждым из {0, 1, 2, 3, 4, 5, 6}
, выполняя gen() % 7
. Это оставляет 65'534
, который отображается на 0
и 65'535
, который отображается на 1
Таким образом, вы видите, что есть смещение в сторону [0, 1]
, чем к [2, 6]
, т.е. *
0
и
1
имеют немного более высокий шанс (
9'363 / 65'536 ≈ 14.28680419921875 %
) появления, чем
2
,
3
,
4
,
5
и
6
(
9'362 / 65'536 ≈ 14.2852783203125 %
).
std::uniformn_distribution
не имеет этой проблемы и использует некоторое математическое вудо с возможностью получения большего числа случайных чисел из генератора для достижения действительно равномерного распределения.