Генерация случайных чисел между двумя числами в Objective-C - PullRequest
49 голосов
/ 13 марта 2012

У меня есть два текстовых поля, и пользователь может ввести 2 натуральных числа (используя Objective-C).Цель состоит в том, чтобы возвратить случайное значение между двумя числами.

Я использовал «man arc4random» и до сих пор не могу обернуть его вокруг себя.Я придумал какой-то код, но он глючит.

float lowerBound = lowerBoundNumber.text.floatValue;
float upperBound = upperBoundNumber.text.floatValue;
float rndValue;
//if lower bound is lowerbound < higherbound else switch the two around before randomizing.
if(lowerBound < upperBound)
{
    rndValue = (((float)arc4random()/0x100000000)*((upperBound-lowerBound)+lowerBound));
}
else 
{
    rndValue = (((float)arc4random()/0x100000000)*((lowerBound-upperBound)+upperBound));
}

Прямо сейчас, если я введу значения 0 и 3, похоже, это будет работать нормально.Однако, если я использую числа 10 и 15, я все равно могу получить значения как 1.0000000 или 2.000000 для «rndValue».

Нужно ли разрабатывать свой алгоритм или мне нужно изменить способ использования arc4random?

Ответы [ 6 ]

121 голосов
/ 13 марта 2012

Вы можете просто использовать целочисленные значения, например:

int lowerBound = ...
int upperBound = ...
int rndValue = lowerBound + arc4random() % (upperBound - lowerBound);

Или, если вы хотите включить число с плавающей точкой между lowerBound и upperBound? Если это так, пожалуйста, обратитесь к этому вопросу: https://stackoverflow.com/a/4579457/1265516

65 голосов
/ 11 декабря 2013

Следующий код включает минимальное значение И МАКСИМАЛЬНОЕ в качестве случайного выходного числа:

- (NSInteger)randomNumberBetween:(NSInteger)min maxNumber:(NSInteger)max
{
    return min + arc4random_uniform((uint32_t)(max - min + 1));
}

Обновление:
Я отредактировал ответ, заменив arc4random() % upper_bound на arc4random_uniform(upper_bound) как предложил @rmaddy.
А вот подробности arc4random_uniform .

Update2:
Я обновил ответ, вставив приведение к uint32_t в arc4random_uniform() как указано @bicycle.

7 голосов
/ 16 октября 2014
-(int) generateRandomNumberWithlowerBound:(int)lowerBound
                               upperBound:(int)upperBound
{
    int rndValue = lowerBound + arc4random() % (upperBound - lowerBound);
    return rndValue;
}
2 голосов
/ 19 июля 2014

Вы должны избегать ограничения значений с помощью mod (%), если можете, потому что даже если используемый генератор псевдослучайных чисел (например, arc4random) хорош для обеспечения равномерно распределенных чисел во всем его диапазоне, он можетне предоставлять равномерно распределенные числа в ограниченном диапазоне по модулю.

Вам также не нужно использовать литерал, такой как 0x100000000, потому что в stdint.h есть удобная константа:

(float)arc4random() / UINT32_MAX

Это даст вам случайное плавание в интервале [0,1].Обратите внимание, что arc4random возвращает целое число в интервале [0, 2 ** 32 - 1].

Чтобы переместить это значение в нужный интервал, вы просто добавляете минимальное значение и умножаете случайное значение с плавающей точкой наразмер вашего диапазона:

lowerBound + ((float)arc4random() / UINT32_MAX) * (upperBound - lowerBound);

В коде, который вы разместили, вы умножаете случайное плавание на весь беспорядок (lowerBound + (upperBound - lowerBound)), который на самом деле просто равен upperBound.И именно поэтому вы по-прежнему получаете результаты, меньшие, чем предполагалось.

0 голосов
/ 24 января 2018

В Свифт:

let otp = Int(arc4random_uniform(6))

Попробуй это.

0 голосов
/ 28 декабря 2017

Функция Objective-C :

-(int)getRandomNumberBetween:(int)from to:(int)to
{
    return (int)from + arc4random() % (to-from+1);
}

Swift:

func getRandomNumberBetween(_ from: Int, to: Int) -> Int 
{
    return Int(from) + arc4random() % (to - from + 1)
}

Звоните куда угодно по :

int OTP = [self getRandomNumberBetween:10 to:99];
NSLog(@"OTP IS %ld",(long)OTP);
NSLog(@"OTP IS %@",[NSString stringWithFormat @"%ld",(long)OTP]);

Для Swift:

var OTP: Int = getRandomNumberBetween(10, to: 99)
...