Генерировать случайные числа между двумя числами в Objective-C
У меня есть два текстовых поля, и пользователь может ввести 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?
Ответы
Ответ 1
Вы можете просто использовать целочисленные значения следующим образом:
int lowerBound = ...
int upperBound = ...
int rndValue = lowerBound + arc4random() % (upperBound - lowerBound);
Или, если вы хотите добавить число с плавающей запятой между lowerBound и upperBound? Если да, обратитесь к этому вопросу: fooobar.com/questions/121622/...
Ответ 2
Следующий код включает минимальное значение И МАКСИМУМ в качестве номера случайного выхода:
- (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()
, как показано на рисунке.
Ответ 3
-(int) generateRandomNumberWithlowerBound:(int)lowerBound
upperBound:(int)upperBound
{
int rndValue = lowerBound + arc4random() % (upperBound - lowerBound);
return rndValue;
}
Ответ 4
Вы можете избегать зажатия значений с помощью mod (%), если можете, потому что даже если генератор псевдослучайных чисел, который вы используете (например, arc4random
), хорош для обеспечения равномерно распределенных чисел в полном диапазоне, он может не обеспечивают равномерно распределенные числа в пределах ограниченного диапазона по модулю.
Вам также не нужно использовать литерал вроде 0x100000000
, потому что в stdint.h:
имеется удобная константа
(float)arc4random() / UINT32_MAX
Это даст вам случайный поплавок в интервале [0,1]. Обратите внимание, что arc4random
возвращает целое число в интервале [0, 2 ** 32 - 1].
Чтобы переместить это в желаемый интервал, вы просто добавляете свое минимальное значение и умножаете случайный float на размер вашего диапазона:
lowerBound + ((float)arc4random() / UINT32_MAX) * (upperBound - lowerBound);
В коде, который вы опубликовали, вы умножаете случайный float на весь беспорядок (lowerBound + (upperBound - lowerBound)), который на самом деле просто равен upperBound. И почему вы все еще получаете результаты меньше, чем ваша предполагаемая нижняя граница.
Ответ 5
Легкий путь от меня:
Функции:
-(int)getRandomNumberBetween:(int)from to:(int)to
{
return (int)from + arc4random() % (to-from+1);
}
Позвоните в любое место:
int OTP = [self getRandomNumberBetween:10 to:99];
NSLog(@"OTP IS %ld",(long)OTP);