Про датчик случайных чисел

21 views
Skip to first unread message

Sergey S. Kumkov

unread,
May 21, 2025, 2:03:07 AMMay 21
to cs_2...@googlegroups.com
Что-то во вторник на лекции так увлекся рассказом про динамические
структуры данных, что забыл рассказать про датчик случайных чисел :(

Краткий конспект рассказа:

1. В целом, идея датчика случайных чисел (ДСЧ) та же, что и в Хаскелле:
где-то внутри системы хранится текущее число x_i. При запросе нового
числа - в Си это функция int rand(void), определённая в библиотеке
stdlib.h - текущее число пеерсчитывается в новое x_{i+1} = f(x_i) с
помощью некоторой "хитрой" функции f. Результат запоминается для
следующего пересчета и выдается в качестве результата запроса.

2. Однако такая схема требует так называемой разгонки ДСЧ - задания
начального значения x_0. По умолчанию оно всегда равно нулю. Так что
программа, использующая ДСЧ, при каждом своем запуске будет получать
"хаотическую" последовательность чисел, но одну и ту же.

3. Присвоение текущего запомненного числа осуществляется процедурой void
srand(int), также определенной в биббиотеке stdlib.h. Имя srand -
сокращение от "seed random", "засеять случайность".

4. Однако использовать srand с какой-либо константой бессмысленно:
последовательность чисел будет другой, чем при стандартном нулевом
начальном значении x_0, но опять той же самой при каждом запуске.

5. Классическое решение - для разгонки ДСЧ брать время запуска
программы, оно, очевидно, будет разным при разных запусках. Для этого
можно использовать функцию int time(int), которая возвращает количество
секунд, прошедших от момента (выраженного так же в секундах),
переданного в качестве аргумента. 0-й момент, "начало времён" - это
00:00:00 01 января 1970 года.

(Кстати, с этим связана ещё одна проблема, подобная проблеме 2000-го
года: а что делать, когда количество секунд от "начала времён" станет
больше максимального значения, хранимого в int, 2^31 - 1 = 2147483647.
Этот момент настанет в 2038 году:
https://ru.wikipedia.org/wiki/Проблема_2038_года )

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

int main (void) {
srand(time(NULL));
// NULL = 0 - считаем количество секунд от начала времен

int ar[10], i;

for (i = 0; i < 10; i++) ar[i] = rand();

return 0;
}

При этом не нужно разгонять ДСЧ перед каждым запросом rand() -
достаточно разогнать один раз в начале программы.


Сергей Кумков

------------------------------
ssk...@gmail.com
Skype: sskumk
mobile: +7(922)2057287
on this number:
WhatsApp, Telegram, Viber
------------------------------

Reply all
Reply to author
Forward
0 new messages