Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Аппаратное обеспечение IBM PC

© Александр Фролов, Григорий Фролов
Том 2, книга 1, М.: Диалог-МИФИ, 1992.

[Назад] [Содеожание] [Дальше]

5.6. Генерация случайных чисел

Последнее, что мы сделаем с таймером - научимся получать от него случайные числа.

Для генерации случайных чисел лучше всего использовать канал 2 в режиме 3. В регистр счетчика канала мы занесем значение, равное диапазону нужных нам случайных чисел. Например, если мы запишем в регистр число 80 и запустим канал таймера, получаемые случайные числа будут лежать в диапазоне от 0 до 79.

Функция rnd_set() предназначена для начальной инициализации генератора случайных чисел:

/**
*.Name         rnd_set
*.Title        Инициализация генератора случайных чисел
*
*.Descr        Эта функция инициализирует канал 2 таймера
*              для использования в качестве генератора
*              случайных чисел.
*
*.Proto        void rnd_set(int bound)
*
*.Params       int bound - верхняя граница для генерируемых
*                          случайных чисел.
*
*.Return       Ничего
*
*.Sample       random.c
**/

#include <stdio.h>
#include <conio.h>

void rnd_set(int bound) {

// Устанавливаем режим 3 для второго канала таймера

        outp(0x43, 0xb6);

// Загружаем регистр счетчика таймера - сначала
// младший, затем старший байты

        outp(0x42, bound & 0x00ff);

        outp(0x42, (bound &0xff00) >> 8);

// Разрешаем работу канала

        outp(0x61, inp(0x61) | 1);
}


Через некоторое время после инициализации с помощью функции rnd_get() можно получить готовое случайное число:

/**
*.Name         rnd_get
*.Title        Получение от таймера случайного числа
*
*.Descr        Эта функция получает случайное число от
*              таймера, который был предварительно
*              проинициализирован функцией rnd_set.
*
*.Proto        int rnd_get(void)
*
*.Params       Отсутствуют.
*
*.Return       Случайное число в диапазоне от 0, до
*              уменьшенного на 1 значения, заданного в
*              качестве параметра функции rnd_set().
*
*.Sample       random.c
**/

#include <stdio.h>
#include <conio.h>

int rnd_get(void) {

        int i;


// Выдаем команду CLC для фиксирования
// текущего значения регистра канала 2 таймера

        outp(0x43, 0x86);


// Вводим младший и старший байты счетчика

        i = inp(0x42);
        i = (inp(0x42) << 8) + i;

        return(i);
}


Для иллюстрации использования этих функций мы подготовили следующую программу:

#include <stdio.h>
#include "sysp.h"


void main(void);
void main(void) {

        int i, j;

        printf("\nГенератор случайных чисел."
                         "\nНажмите любую клавишу,"
                         "\nдля завершения работы нажмите CTRL-C."
                         "\n");

        for(;;) {

// Устанавливаем диапазон генерации случайных
// чисел и инициализируем таймер

                rnd_set(80);

// Ожидаем нажатия клавиши.

                getch();

// После нажатия на клавишу получаем
// случайное число

                j = rnd_get();

// Выводим на экран строку символов "-",
// длина которой равна полученному случайному
// числу.

                for(i=0; i < j; i++) putchar(219);

                printf("\n");
        }

}


Программа получает случайные числа и отображает их в наглядном виде с помощью столбчатой диаграммы:

Генератор случайных чисел.
Нажмите любую клавишу,
для завершения работы нажмите CTRL-C.

--------------------------
------------------------------------------------
------
--------------------------------------
------------------
------------------------------------------------------------------
------------------------
------------------------------------------------------
------------------------------------------------------
--
----------------------------------
--------------
--------------
------------------------------------------------------------------------
------------------------------
----------------------------------------------------------
--------------------------------
------------------------------------------------------------------
----------------------------------------------------
------------------------------------------
----------------------------------------------------------
----------------------------------------
----------------------
[Назад] [Содеожание] [Дальше]