RAND_MAX
обычно 2^31 - 1
, поэтому оно равно 2147483647
.
Но давайте для простоты предположим, что у нас очень странная система с RAND_MAX
= 100 (так что rand()
можетвернуть 0
в 100
, это 101 число).И давайте предположим, что функция rand()
имеет идеальное равномерное распределение .
Теперь, какова вероятность rand() % 100
?Числа от 1
до 99
имеют одинаковую вероятность, то есть 1/101
.Но 0
имеет вероятность 2/101
, потому что когда rand()
возвращает 0
и когда rand()
возвращает 100
, выражение rand() % 100
будет равно 0
.Так что 0
может приходить чаще, чем любые другие числа, фактически в два раза чаще.Таким образом, наше распределение двузначных чисел с rand() % 100
не является равномерным.
Теперь текст предлагает решение проблемы.Предлагаемое решение состоит в том, чтобы разбить область от 0
до RAND_MAX
на 100 четных частей, чтобы числа в каждой части имели одинаковую вероятность.Затем бросьте rand()
и посмотрите, в каком регионе закончился номер.Если RAND_MAX
равно 2147483647
и мы, например, получаем число 279172968
, мы видим, что оно заканчивается в 13-й области - между RAND_MAX / 100 * 13 = 279172868
и RAND_MAX / 100 * 14 = 300647704
.
Решение также имеет недостатки, так какмы можем видеть, что невозможно разделить 0
на RAND_MAX
на 100 четных частей, когда RAND_MAX % 100
не равно 0
.
Я чувствую, что единственное жизнеспособное решение - отбросить все числабольше RAND_MAX / 100 * 100
(используется целочисленная арифметика C).Остальные числа будут иметь равномерное распределение, а максимум будет делиться на 100, поэтому с остальными мы можем просто rand() % 100
.Вот как то так:
int get_2_digit_number() {
int r = 0;
while (1) {
r = rand();
if (r > (RAND_MAX / 100 * 100)) {
continue;
}
break;
}
return r % 100;
}