Соотношение смешанного конгруэнтного метода выглядит так: Xn+1=(aXn+c) mod m, где n > 0.
При правильном подборе начальных значений элементов кроме
увеличения периода последовательности случайных чисел уменьшается
корреляция (зависимость) получаемых случайных чисел.
На значения накладываются ограничения:
- Х0>0;
- а=21+1, где 1>=2;
- с>0 взаимно просто с m (это выполнимо, если с — нечетно, а т=2р, где (р>=2)
- m=2р (р>=2) и т кратно 4.
:rand_mix_cong_l.asm - датчик линейной (смешанной)
:конгруэнтной последовательности случайных чисел (с>0).
:Вход: Хо. а. с. m - в соответствии с указанными выше
ограничениями.
:Выход: dl - значение очередного случайного числа.
.data
m db 128 ; 128=27
a db 9
х db 3 начальное значение
с dw 3
.code
mov cl.7 :значение степени m=27 в cl ;первое число в
последовательности х=3 cycl: вычисляем очередное случайное число Х=(а*Х)
mod m
mov al.x
mul a :a*x в ah:al
add ax,с
shrd ax.ax.cl
xor al.al
rol ax.cl :b al случайное число :вывод в файл - командная строка rand_mult_cong.exe > p.txt
end_cycl:
Величина периода случайной последовательности, получаемой с помощью данной программы, составляет 128 значений. Сегмент кода программы rand_mix_ cong_1.asm можно оформить в виде процедуры. Начальное значение Хо можно выбирать двумя способами: задавать константой в программе или генерировать случайным образом. В последнем случае можно использовать такты системного таймера, как в следующей макрокоманде:
rCMOS macro
макрокоманда чтения значений CMOS
:на входе: al адрес ячейки, значение которой читаем
:на входе-выходе: al - прочтенное значение
out 70h,al
хог ах,ах :вводим в регистр AL из порта значение ячейки cmos
in al.71h
endm .code
:получить значение секунд из CMOS для x_start mov al.00 rCMOS mov x.al :x=x_start
Таким способом можно получить начальное значение из диапазона 0..59. Для получения большего по величине начального значения можно использовать величину размером 32 бита из области данных BIOS по адресу 0040:006с. Здесь содержится счетчик прерываний от таймера. Извлечь это значение можно, используя следующий программный фрагмент:
push ds
push 40h
pop ds
mov eax.dword ptr ds:006ch
popds
Заменяя команду MOV командами MOV AX,word ptr ds:006ch
или MOV AL, byte ptr ds:006ch, можно использовать младшие 8 или 16 бит
значения из этой области BIOS. Команда MOV AL, byte ptr ds:006ch
позволяет случайным образом получить в регистре AL значение из диапазона
00.. f fh.
Попытки создать программный датчик случайных чисел без опоры на
какую-либо теорию обречены на провал. Рассмотрим еще несколько способов
генерации случайных чисел.