(rand7() * rand7()) % 10
не подойдет, поскольку некоторые значения будут более вероятными, чем другие.
Давайте сравним вероятность получения 1 и 2:
Чтобы получить 1:
rand7() * rand7()
должно быть равно 1, 11, 21, 31 или 41.
- Это может быть достигнуто следующими способами: 1 * 1, 3 * 7 или 7 * 3.
- То есть 3 раза из 49 вы получите 1
Чтобы получить 2: ,
rand7() * rand7()
должно быть равно 2, 12, 22, 32 или 42.
- Это может быть достигнуто следующими способами: 1 * 2, 2 * 1, 3 * 4, 4 * 3, 2 * 6, 6 * 2, 6 * 7, 7 * 6.
- То есть 8 из 49 вы получите 2!
Их решение решает эту проблему, позволяя каждому числу (от 1 до 10) быть одинаково вероятным: каждое число встречается 4 раза в 49 возможных исходах (9 результатов отбрасываются и приводят к повторной выборке).
По сути, реализация Random.nextInt(int n)
делает нечто подобное:
int bits, val;
do {
bits = next(31);
val = bits % n;
} while (bits - val + (n-1) < 0); // re-sample until in range.
return val;
Это фактически использует rand2
для реализации randN
.