Функция random — генератор случайных чисел в Pascal

Создано: 12.04.2026

До сих пор мы "вносили разнообразие" в поведение той или иной программы с помощью ввода данных с клавиатуры. Получая разные данные, программа выдавала разный результат, даже если обрабатывала их одним и тем же алгоритмом. Но что если мы хотим получать разный результат без ввода данных. Можно ли сама программа генерировать некую случайность или ее подобие?

Да, может. В языках программирования обычно есть предопределенные функции, которые выдают случайные (а скорее псевдослучайные) числа. В Pascal за это отвечает функция random, которая выдает либо вещественные числа, либо целые, в зависимости от того, вызывается ли она без параметра или с ним. Параметр функции — это то, что указывается в скобках.

Вызов функции без параметра, то есть в виде random() или random, возвращает вещественное случайное число в диапазоне от нуля (включительно) до единицы, т.е. [0, 1). В программе ниже мы с помощью цикла 5 раз генерируем дробное число, каждый раз присваиваем его переменной a и выводим ее значение на экран.

var 
    a: real;
    i: integer;
begin    

    for i:=1 to 5 do begin
        a := random;
        write(a:6:2);
    end;

    writeln;
end.
  0.55  0.59  0.72  0.84  0.60

Даже если цикл прокрутится не 5 раз, а 100, вся сотня сгенерированных значений будет находится в пределах диапазона от нуля до единицы.

Если в скобках функции random() указан целочисленный параметр, то она возвращает целое число от 0 до указанного в скобках (не включая само значение). Так выражение random(10) говорит о том, что будет получено любое число в диапазоне [0, 10). Выражение random(-100) сгенерирует число в диапазоне (-100, 0].

var 
    a, i: integer;
begin    

    for i:=1 to 7 do begin
        a := random(100);
        write('  ', a);
    end;

    writeln;
end.
  54  59  71  84  60  85  54

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

Задумаемся, а откуда в самом языке программирования возьмется случайность? Random — это встроенная функция. Значит, где-то в стандартной библиотеки Паскаля есть ее программный код. Он реализует алгоритм генерации одного случайного числа. Но откуда он берет исходны данные для хоть какой-то случайности, чего-то неизвестного хотя бы нам? На самом деле в самой функции взяться случайности неоткуда. Она использует значение определенной встроенной переменной, играющей роль "зерна", для вычисления по формуле первого "случайного" числа, а это полученное новое число присваивает "зерну". Следующее "случайное" число будет вычисляться от этого нового "зерна". И так далее.

В Паскале "зерно" исходно равно нулю. Это можно увидеть, если выполнить команду writeln(RandSeed). Однако значение "зерна" можно менять. Обычно для этого используется вызов процедуры randomize. Тогда возникает вопрос, откуда в ней берется случайность? В ней самой тоже ниоткуда. Просто эта процедура "выходит во внешний мир" и берет время с системных часов компьютера. Для нас оно в достаточной степени случайно. Randomize присваивает полученное значение переменной randseed, и "зерно" перестает быть равным нулю.

Таким образом, если в начале программы использовать randomize, то при каждом запуске ряд чисел будет другим, что уже более походит на настоящую случайность.

Перепишите одну из приведенных выше программ, добавив в нее randomize. Выполните программу несколько раз. Разные ли ряды чисел вы видите на экране? Теперь вместо randomize вручную присвойте новое значение целочисленной встроенной переменной RandSeed. Чем отличается такой способ изменения "зерна" от варианта с randomize?

Итак, мы знаем как получать случайные числа в диапазонах от нуля. Однако может быть нужно получать значения в каком-либо другом диапазоне (не от нуля). В этом случае в Паскале прибегают к арифметическим операциям. Например, чтобы получить случайное число от -100 до 100, надо записать такое выражение: random(200) - 100. В результате его выполнения сначала будет получено число из диапазона [0, 199], а затем из него будет вычтена сотня. И если случайное число было меньше 100, то результат выражения будет отрицательным.

var a: integer;
begin
    randomize;
    a := random(200) - 100;  // [-100, 100)
    writeln(a);
    a := random(7) + 5;  //  [5, 12)
    writeln(a);
    a := random(-10) - 1; // [-1, -10] или [-1, -11)
    writeln(a);
end.

Пример выполнения:

-71
6
-10

Напишите программу, в которой переменной n присваивается случайное значение в диапазоне [5, 10]. Значение n используется для определения количества повторов цикла for. В цикле for генерируются случайные числа в диапазоне [-50, 49) и выводятся на экран.

Получение случайного вещественного числа в любом диапазоне, происходит не так как целого. Допустим, нам надо получить вещественное число от 0 до 10. При этом мы знаем, что random выдает дробное число от 0 до 1. Если его умножить на 10, то получится как раз то, что нам надо:

for i:=1 to 5 do begin
    a := random * 10;
    write(a:6:1);
end;
   2.5   1.3   7.0   2.8   6.7

Если диапазон не от нуля, то умножать надо на размер диапазона (верхняя граница минус нижняя), а потом прибавлять минимальную границу (если она отрицательная, то получится вычитание).

a := random * 10 - 5;    // [-5, 5)
b := random * 2 - 1;     // [-1, 1)
c := random + 3;         // [3, 4)
d := random * 20 + 100;  // [100, 120)

Это похоже на получение целого числа, только там мы не умножали на размер диапазона, а передавали его в качества параметра в функцию random. Таким образом, мы приходим к формулам генерации случайного числа в любом диапазоне [x, y). Для целого:

random(y-x) + x

Для вещественного:

random * (y-x) + x

Задания для дополнительной или самостоятельной работы:

Разработайте одну программу, которая позволяет пользователю самому вводить зерно для генератора случайных чисел, а также указывать границы диапазона случайных чисел и определять, сколько их должно быть.