Основы программирования на языке C

Функция получения случайных чисел


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

Схема начинает с числа, называемого "зерно". Она использует его для создания нового числа, которое становится новым зерном. Затем новое зерно можно использовать для создания более нового зерна и т.д. Чтобы эта схема работала, функция случайных чисел должна помнить зерно, которое она использовала при последнем вызове. Отметим, здесь нужно использовать статическую переменную!

/* Первая версия функции rand( )*/ rand( ) { static int randx = 1; randx = (randx * 25173 + 13849)%65536; /* магическая формула */ return(randx); }

Статическая переменная randx начинает со значения 1 и изменяется при помощи магической формулы каждый раз при вызове функции. Результатом в нашей системе является число, находящееся в диапазоне -32768 до 32767. Системы с разной длиной переменной типа int будут давать различные результаты.

Проверим работу функции при помощи этого простого драйвера:

/*драйвер 1 функции rand( ) */ main( ) { int count; for(count = 1; count <= 5; count++) printf(" %d\n",rand( )); }

Получим результат:

-26514 -4449 20196 -20531 3882

Эта последовательность чисел выглядит довольно случайной. Запустим драйвер еще раз. Теперь имеем

-26514 -4449 20196 -20531 3882

Получилось абсолютно то же самое. Это и есть псевдоэффект. Каждый раз, когда работает основная программа, мы начинаем с одного и того же значения зерна, равного 1. Можно обойти эту проблему, введя вторую функцию srand( ), которая позволяет вновь устанавливать зерно в начальное значение. Хитрость заключается в том, чтобы сделать randx внешней статической переменной, известной только функциям rand( ) и srand( ). Эти две функции нужно хранить в своем собственном файле и компилировать этот файл отдельно. Вот модификатор программы:

/* Файл для rand( ) и srand( ) */ static int randx = 1; rand( ) { randx = (randx * 25173 + 13849) % 65536; return(randx); } srand(x) unsigned x; { randx = x; }


Используем другой драйвер:

/* драйвер 2 функции rand( ) */ main( ) { int count; int seed; printf(" Введите свое значение зерна.\n"); scanf("%d", & seed); srand(seed); /* установите зерно в начальное значение */ for(count = 1; count <= 5; count++) printf("%\n",rand( )); }

Программа проработала один раз:

Введите свое значение зерна.

1 -26514 -4449 20196 -20531 3882

Используя значение 1 для переменной seed, получаем те же значения, что и прежде. Введем значение 2 и посмотрим, что получится:

2 23832 20241 -1858 -30417 -16204

Мы получили другую последовательность чисел.

Содержание раздела