Прототип функции rand:
Функция rand генерирует случайные числа, возвращает псевдослучайное целое число в диапазоне от 0 до RAND_MAX .
Это число генерируется алгоритмом, который возвращает последовательность псевдо-случайных чисел. Этот алгоритм использует своего рода «семя» — число, для создания серий случайных чисел. То есть, если семя всегда будет одно и то же, то сгенерированная последовательность чисел не будет меняться, исчезнет фактор стохастичности.
RAND_MAX это константа, определенная в . По умолчанию её значение может изменяться, в зависимости от реализации, но, как правило, макрос RAND_MAX меньше значения 32767 не бывает.
Типичный способ генерации псевдослучайных чисел в определенном диапазоне с использованием функции rand выполняется следующим образом:
(value % 100) — генерация чисел в диапазоне от 0 до 99
(value % 100 + 1) — генерация чисел в диапазоне от 1 до 100
(value % 30 + 1985) — генерация чисел в диапазоне от 1985 до 2014
Однако, использование операции остаток от деления не создает поистине равномерно распределенных случайных чисел в заданном диапазоне, но, как правило, такой способ генерации чисел является хорошим приближением для небольших диапазонов.
Параметры:
Функция не принимает аргументов.
Возвращаемое значение
Целое псевдослучайное число в диапазоне от 0 до RAND_MAX .
Пример: исходный код программы
//пример использования функции rand #include #include #include int main () < int guess; srand ( time(NULL) ); // инициализация функции rand значением функции time int secret = rand() % 10 + 1; // сгенерировать секретное число do < std::cout > guess; if (secret < guess) std::cout guess) std::cout while (secret != guess); std::cout
Пример работы программы
CppStudio.com
Отгадайте число (от 1 до 10): 4
Секретное число меньше
Отгадайте число (от 1 до 10): 2
Мои поздравления.
В этом примере, случайное зерно генерируется функцией time (функция time определена в заголовке ). Использование данной функции — простой и достаточно хороший вариант генерации зерна.
Что такое rand в C++?
Для генерации случайных чисел необходимо использовать метод rand() . Чтобы создать случайное число в диапазоне от 1 до 20 потребуется следующий код:
int num = 1 + rand() % 20;
Кроме того, у вас могут возникать проблемы с тем, что постоянно выводиться одно и тоже самое число. Чтобы такого не было подключите библиотеку #include
#include #include using namespace std; int main() < setlocale(LC_ALL, "Russian"); // Русская локализация консоли srand(time(NULL)); // Генерирует случайное число, используя текущую дату как параметр cout
Для работы со строками необходимо подключить библиотеку #include
rand
Создает псевдослучайное число. Доступна более программно безопасная версия этой функции; см. раздел rand_s . Числа, созданные rand не криптографически безопасными. Для более криптографически безопасного создания случайных чисел используйте rand_s или функции, объявленные в стандартной библиотеке C++ в .
Синтаксис
int rand(void);
Возвращаемое значение
Функция rand возвращает псевдослучайное число, как описано выше. Не возвращается ошибка.
Замечания
Функция rand возвращает псевдослучайное целое число в диапазоне от 0 до RAND_MAX (32767). Используйте функцию srand для заполнения генератора псевдорандомных чисел перед вызовом rand .
Функция rand создает известную последовательность и не подходит для использования в качестве криптографической функции. Для более криптографически безопасного создания случайных чисел используйте rand_s или функции, объявленные в стандартной библиотеке C++ в .
По умолчанию глобальное состояние этой функции ограничивается приложением. Чтобы изменить это поведение, см . статью "Глобальное состояние" в CRT.
Требования
| Маршрут | Обязательный заголовок |
|---|---|
| rand |
Дополнительные сведения о совместимости см. в разделе Совместимость.
Пример
// crt_rand.c // This program seeds the random-number generator // with a fixed seed, then exercises the rand function // to demonstrate generating random numbers, and // random numbers in a specified range. #include // rand(), srand() #include // printf() void SimpleRandDemo(int n) < // Print n random numbers. for (int i = 0; i < n; i++) < printf(" %6d\n", rand()); >> void RangedRandDemo(int range_min, int range_max, int n) < // Generate random numbers in the interval [range_min, range_max], inclusive. for (int i = 0; i < n; i++) < // Note: This method of generating random numbers in a range isn't suitable for // applications that require high quality random numbers. // rand() has a small output range [0,32767], making it unsuitable for // generating random numbers across a large range using the method below. // The approach below also may result in a non-uniform distribution. // More robust random number functionality is available in the C++ header. // See https://learn.microsoft.com/cpp/standard-library/random int r = ((double)rand() / RAND_MAX) * (range_max - range_min) + range_min; printf(" %6d\n", r); > > int main(void) < // Seed the random-number generator with a fixed seed so that // the numbers will be the same every time we run. srand(1792); printf("Simple random number demo ====\n\n"); SimpleRandDemo(10); printf("\nRandom number in a range demo ====\n\n"); RangedRandDemo(-100, 100, 100000); >``` ```Output Simple random number demo ==== 5890 1279 19497 1207 11420 3377 15317 29489 9716 23323 Random number in a range demo ==== -82 -46 50 77 -47 32 76 -13 -58 90
Случайные числа в языке C
В языках программирования обычно предусмотрены функции, позволяющие генерировать случайные числа в определенном по умолчанию диапазоне. На самом деле генерируются не случайные, а так называемые псевдослучайные числа; они выглядят случайно, но вычисляются по вполне конкретной формуле. Далее для простоты мы все равно будем называть их случайными.
В языке программирования C получить случайное число можно с помощью функции rand() , которая входит в стандартную библиотеку языка. Эта функция не принимает никакие параметры.
#include #include int main() { int a = rand(); printf("%d\n", a); }
Функция rand() возвращает целое число от 0 до значения присвоенного константе RAND_MAX . Значение RAND_MAX зависит от системы и определено в заголовочном файле stdlib.h. Так, например, оно может быть равно 32767 (двухбайтовое целое) или 2147483647 (четырехбайтовое целое).
int a = RAND_MAX; printf("%d\n", a); // 2147483647
Код ниже выводит на экран 50 случайных чисел:
for (int i = 1; i 50; i++) { printf("%15d", rand()); if (i % 5 == 0) printf("\n"); }
В теле цикла осуществляется переход на новую строку после каждых выведенных на экран пяти чисел. Для этого используется выражение, в котором находится остаток от деления i на 5, результат сравнивается с 0. Чтобы после первого числа не происходил переход на новую строку, i сначала присваивается единица, а не ноль (т.к. 0 делится на 5 без остатка).
При выполнении программы с таким кодом пятьдесят чисел будут разными. Однако если запустить программу снова, набор чисел окажется такими же, как в предыдущем выполнении. Даже если вы перекомпилируете программу, результат не изменится. Данный эффект связан с тем, что начальное (инициализирующее) число, которое подставляется в формулу вычисления первого и последующих псевдослучайных чисел, для каждой системы всегда одно и то же. Однако это начальное число можно изменить с помощью функции srand() , которой в качестве параметра передается любое целое число. Понятно, что если вы зададите конкретный аргумент для функции, например, srand(1000) , то от вызова к вызову программы числа будут также одни и те же. Хотя и не те, что были бы без srand() . Поэтому появляется проблема, как сделать так, чтобы аргумент для srand() был тоже случайным? Получается замкнутый круг.
Инициирующее значение можно запрашивать у пользователя с помощью scanf() и передавать его в srand() .
scanf("%d", &n); srand(n);
Однако чаще всего это не является полноценным выходом из ситуации. Поэтому инициализирующее значение привязывают к какому-либо процессу, протекающему в операционной системе, например, к часам. Время (учитывая не только время суток, но и дату) никогда не бывает одинаковым. Значит значение для srand() , преобразованное в целое из системного времени, будет различным.
Текущее время можно узнать с помощью функции time() , прототип которой описан в файле time.h. Передав time() в качестве параметра NULL , мы получим целое число, которое можно передать в srand() :
srand(time(NULL));
Получение целых случайных чисел в заданных диапазонах
Функция rand() выдает случайное число от 0 до значения RAND_MAX . Что делать, если требуется получать случайные числа в иных диапазонах, например, от 100 до 999?
Сначала рассмотрим более простую ситуацию: получить случайные числа от 0 до 5. Если любое целое число попытаться разделить на 5 нацело, то в качестве остатка можно получить как 0 (когда число делится на 5 без остатка), так и 1, 2, 3, 4. Например, rand() вернула число 283. Применяя к этому числу операцию нахождения остатка от деления на 5, получим 3. Т.е. выражение rand() % 5 дает любое число в диапазоне [0, 5).
Однако, что если надо, чтобы число 5 так же входило в диапазон, т.е. диапазон имеет вид [0, 5]? Логично предположить, что следует найти остаток от деления на 6. При этом более грамотным будет следующее рассуждение: надо находить остаток от деления на размер диапазона. В данном случае он равен шести значениям: 0, 1, 2, 3, 4, 5. Чтобы найти размер диапазона, надо из допустимого максимума вычесть допустимый минимум и прибавить единицу: max - min + 1. Будьте внимательны: если, например, требуется, чтобы указанный в задаче максимум не входил в диапазон, то единицу прибавлять не надо или надо вычитать единицу из максимума.
Следующее выражение выведет на экране случайное число от 0 до 99 включительно:
printf("%d\n", rand() % 100);
Итак, мы знаем формулу получения длины диапазона: max - min + 1. Если требуется получить число от 6 до 10 включительно, то длина диапазона будет равна 10 - 6 + 1 = 5. Выражение rand()% 5 даст любое число от 0 до 4 включительно. Но нам надо от 6 до 10. В таком случае достаточно к полученному случайному остатку прибавить 6, т.е. минимум. Другими словами, надо выполнить сдвиг. Действительно, для приведенного примера:
- если остаток был равен 0, то добавляя 6, получаем 6;
- остаток 1, добавляем 6, получаем 7;
- …
- остаток 4, прибавляем 6, получаем 10;
- остатка больше 4 не может быть.
В таком случае формула для получения случайного числа в диапазоне [a, b] выглядит так:
rand() % длина_диапазона + сдвиг
где длина_диапазона вычисляется как b - a + 1, сдвиг является значением a .
В эту формулу также вписываются случаи, когда необходимо получить случайное число от 0 до N, т.е. они являются ее частными случаями.
Выведите на экран ряд случайных чисел, принадлежащих диапазону от 100 до 299 включительно.
С таким же успехом можно получать случайные отрицательные числа. Если диапазон задан как [-35, -1], то его длина будет равна -1 - (-35) + 1 = 35, что соответствует действительности; выражение получения случайного числа будет выглядеть так:
rand() % 35 - 35
Так, если остаток от деления составил 0, то мы получим -35, а если 34, то -1. Остальные остатки дадут значения в промежутке от -35 до -1.
Выведите на экран ряд случайных чисел, принадлежащих диапазону от -128 до 127 включительно.
Получение вещественных случайных чисел
Ситуация с вещественными числами выглядит несколько по-иному. Во-первых, мы не можем получить остаток от деления, если делимое или делитель дробные числа. Во вторых при вычислении длины диапазона нельзя прибавлять единицу.
Поясним вторую причину. Допустим диапазон задан как [2.50, 5.30]. Он состоит не из определенного количества чисел (как в случае целых), а из неопределенного (можно сказать, бесконечного) числа значений, т.к. вещественные числа можно представлять с различной степенью точности. Позже выполняя округление все равно будет шанс получить максимальную границу диапазона, поэтому для вычисления длины диапазона достаточно из максимума вычесть минимум.
Если разделить случайное число, преобразованное к вещественному типу, которое выдала функция rand() , на значение константы RAND_MAX , то получится вещественное случайное число от 0 до 1. Теперь, если это число умножить на длину диапазона, то получится число, лежащее в диапазоне от 0 до значения длины диапазона. Далее если прибавить к нему смещение к минимальной границе, то число благополучно впишется в требуемый диапазон. Таким образом формула для получения случайного вещественного числа выглядит так:
(float) rand() / RAND_MAX * (max - min) + min
Заполните массив случайными числами в диапазоне от 0.51 до 1.00. Выведите значение элементов массива на экран.
Равновероятные случайные числа
Функция rand() генерирует любое случайное число от 0 до RAND_MAX с равной долей вероятности. Другими словами, у числа 100 есть такой же шанс выпасть, как и у числа 25876.
Чтобы доказать это, напишем программу, подсчитывающую количество выпадений каждого из значений. Если выборка (количество "испытуемых") будет достаточно большой, а диапазон (разброс значений) маленьким, то мы должны увидеть, что процент выпадений того или иного значения приблизительно такой же как у других.
#include #include #define N 500 int main () { int i; int arr[5] = {0}; srand(time(NULL)); for (i=0; i N; i++) switch (rand() % 5) { case 0: arr[0]++; break; case 1: arr[1]++; break; case 2: arr[2]++; break; case 3: arr[3]++; break; case 4: arr[4]++; break; } for (i=0; i 5; i++) printf("%d - %.2f%%\n", i, ((float) arr[i] / N) * 100); }
В приведенной программе массив из пяти элементов сначала заполняется нулями. Случайные числа генерируются от 0 до 4 включительно. Если выпадает число 0, то увеличивается значение первого элемента массива, если число 1, то второго, и т.д. В конце на экран выводится процент выпадения каждого из чисел.
Чем больше значение константы N, тем меньше будут отличаться между собой проценты выпадения каждого из чисел.
Курс с решением задач:
pdf-версия