Создать случайное число в пределах диапазона?
Возможный дубликат:
Генерация случайных чисел в Objective-C
Как мне сгенерировать случайное число, которое находится в пределах диапазона?
5 ответов
Это на самом деле немного сложнее, чем большинство людей понимают:
int rand_lim(int limit) {
/* return a random number between 0 and limit inclusive.
*/
int divisor = RAND_MAX/(limit+1);
int retval;
do {
retval = rand() / divisor;
} while (retval > limit);
return retval;
}
Попытки, которые просто используют %
(или, что эквивалентно, /
) для получения чисел в диапазоне почти неизбежно вводится перекос (т. е. некоторые числа будут генерироваться чаще, чем другие).
Что касается использования %
дает искаженные результаты: если нужный диапазон не является делителем RAND_MAX, перекос неизбежен. Если вы начнете с небольших чисел, понять, почему это довольно просто. Подумайте о том, чтобы взять 10 конфет и попытаться равномерно распределить их между тремя детьми. Ясно, что это невозможно сделать - если вы раздаете все конфеты, самое близкое, что вы можете получить, - это чтобы два ребенка получили три кусочка конфеты, а один из них - четыре.
У всех детей есть только один способ получить одинаковое количество конфет: убедитесь, что вы вообще не раздаете последний кусочек конфеты.
Чтобы связать это с приведенным выше кодом, давайте начнем с нумерации конфет от 1 до 10, а для детей - от 1 до 3. Начальное деление говорит, что, поскольку детей три, наш делитель - три. Затем мы вытаскиваем случайную конфету из ведра, смотрим на ее число, делим на три и даем ее этому ребенку - но если результат больше 3 (то есть мы выбрали конфету № 10), мы просто не раздайте это вообще - мы отбрасываем это и выбираем другую конфету.
Конечно, если вы используете современную реализацию C++ (т.е. ту, которая поддерживает C++11 или более новую версию), вам обычно следует использовать одну из distribution
занятия из стандартной библиотеки. Код выше соответствует наиболее близко к std::uniform_int_distribution
, но стандартная библиотека также включает в себя uniform_real_distribution
а также классы для ряда неоднородных распределений (Бернулли, Пуассон, нормальный, возможно, пара других, которых я не помню в данный момент).
int rand_range(int min_n, int max_n)
{
return rand() % (max_n - min_n + 1) + min_n;
}
Для фракций:
double rand_range(double min_n, double max_n)
{
return (double)rand()/RAND_MAX * (max_n - min_n) + min_n;
}
Для целочисленного значения в диапазоне [min,max):
double scale = (double) (max - min) / RAND_MAX;
int val = min + floor(rand() * scale)
http://www.cprogramming.com/tutorial/random.html
Второй пример показывает, как генерировать по диапазону
Я написал это специально в Obj-C для проекта iPhone:
- (int) intInRangeMinimum:(int)min andMaximum:(int)max {
if (min > max) { return -1; }
int adjustedMax = (max + 1) - min; // arc4random returns within the set {min, (max - 1)}
int random = arc4random() % adjustedMax;
int result = random + min;
return result;
}
Использовать:
int newNumber = [aClass intInRangeMinimum:1 andMaximum:100];
Добавить соль по вкусу
+(NSInteger)randomNumberWithMin:(NSInteger)min WithMax:(NSInteger)max {
if (min>max) {
int tempMax=max;
max=min;
min=tempMax;
}
int randomy=arc4random() % (max-min+1);
randomy=randomy+min;
return randomy;
}
Я использую этот метод в классе, связанном со случайными числами, который я сделал. Хорошо работает для моих нетребовательных потребностей, но вполне может быть предвзятым.