#objective-c #random
#objective-c #Случайный
Вопрос:
Я знаю, что :
randNum = arc4random_uniform(N);
Установит randNum в случайное число от 0 до N — 1.
Однако, как я могу изменить приведенное выше утверждение, чтобы получить случайное четное число от 0 до N — 1?
Комментарии:
1.
randNum = 2 * arc4random_uniform(N / 2);
2. И выключайте младший бит каждый раз после получения случайного числа.
Ответ №1:
Это быстрее, используя побитовый оператор, очистите младший бит, как сказал @Gallymon.
unsigned int evenNumber = arc4random_uniform(N) amp; 0xFFFFFFFE ;
Ответ №2:
@user3477950 дал вам правильный ответ.
Хотя обычной практикой является использование модуля как способа уменьшения ограничений, например: randEvenNum = 2*(arc4random_uniform(N) % (N/2))
, это небезопасно для произвольных модулей, поскольку это приводит к искажению плотности вероятности случайного числа. Таким образом, лучше поступить так, как предлагает @user3477950, и использовать функцию для создания равномерного распределения по половине вашего пространства, а затем удвоить амплитуду (операция, которая не влияет на плотность вероятности)
В качестве примера представьте, что у вас есть генератор, который производит равномерное распределение между 0-5 включительно. Вы хотите, чтобы оно включало 0-3, поэтому вы говорите: «Эй, давайте изменим на 3 1, и у нас будет наш генератор. Проблема с этим заключается в том, что если плотность вашего генератора равна 1/6 для всех чисел 0-5 изначально, то когда вы берете этот модуль,
{0,4} -> 0
{1,5} -> 1
{2} -> 2
{3} -> 3
Плотность вероятности больше не является плоской. У нас было:
{1/6, 1/6, 1/6, 1/6, 1/6, 1/6}
И теперь у нас есть
{1/3, 1/3, 1/6, 1/6}
Когда то, что мы хотели, было
{1/4, 1/4, 1/4, 1/4}
arc4random()
Функция представляет собой алгоритм, созданный RSA, и имеет довольно высокую энтропию. Более подробные результаты потребуют анализа. Однако, предполагая, что функция создает очень равномерную плотность между 0 и N-1, тогда лучший ответ на ваш вопрос:
randEvenNum = 2*arc4random_uniform(N/2);