Генерировать случайное число в диапазоне? [дубликат]

15
задан Community 23 May 2017 в 11:54
поделиться

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 или новее), вам обычно следует использовать один из классов дистрибутива из стандартной библиотеки. Приведенный выше код наиболее близко соответствует std :: uniform_int_distribution , но стандартная библиотека также включает uniform_real_distribution , а также классы для ряда неоднородных распределений (Бернулли, Пуассона, нормальное, нормальное, нормальное, может быть пара других, которых я не помню в данный момент).

67
ответ дан 30 November 2019 в 23:52
поделиться

Я написал это специально в 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]; 

Добавьте соли по вкусу

-1
ответ дан 30 November 2019 в 23:52
поделиться

Для целочисленного значения в диапазоне [min, max):

double scale = (double) (max - min) / RAND_MAX;
int val = min + floor(rand() * scale) 
2
ответ дан 30 November 2019 в 23:52
поделиться
+(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;
}

Я использую этот метод в созданном мной классе, относящемся к случайным числам. Хорошо подходит для моих нетребовательных потребностей, но вполне может быть в чем-то предвзятым.

-2
ответ дан 30 November 2019 в 23:52
поделиться
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;
}
8
ответ дан 30 November 2019 в 23:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: