Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Клуб программистов > Обсуждение статей
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.03.2017, 08:17   #1
newerow1989
Я самый любопытный
Участник клуба
 
Аватар для newerow1989
 
Регистрация: 24.07.2012
Сообщений: 1,945
По умолчанию статья - Генератор случайных чисел. Как образуются случайные числа?

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

1. Как работает процедура Randomize?

Процедура Randomize инициализирует генератор случайных чисел, задавая значение переменной RandSeed, вычисленное с помощью системных часов.

Код:
procedure Randomize;
var SystemTime: TSystemTime;
begin
   GetSystemTime(SystemTime);
   With SystemTime do
      RandSeed:=((wHour*60 + wMinute)*60 + wSecond)*1000 + wMilliseconds;
end;
2. Как работает функция Random?

Рассмотрим работу функции для целых чисел.

Код:
function Random(Range: integer): integer;
var z: int64;
begin
   RandSeed:=RandSeed*$8088405 + 1;
   z:=RandSeed;
   If z<0 then
      z:=z+$100000000;
   z:=z*Range;
   Result:=z div $100000000;
end;
Согласно этой функции, последовательность чисел зависит от переменной RandSeed. Но, если значение переменной RandSeed будет всегда одинаковым, то мы получим одинаковый набор случайных чисел.
Еще одна особенность заключается в том, что переменная RandSeed всегда изменяется при вызове функции Random, т.е. устанавливает генератор случайного числа на следующее значение.

Напишем эту функцию на ассемблере.
Код:
function Random(Range: integer): integer;
asm
   MOV EAX,Range
   IMUL EDX,RandSeed,$8088405
   INC EDX
   MOV RandSeed,EDX
   MUL EDX
   MOV Result,EDX
end;
Рассмотрим работу функции для вещественных (дробных) чисел.

Код:
function Random: extended;
const two2neg32 = 1/$100000000; // 2^-32
var z: int64;
begin
   RandSeed:=RandSeed*$8088405 + 1;
   z:=RandSeed;
   If z<0 then
      z:=z+$100000000;
   Result:=z*two2neg32;
end;
Напишем эту функцию на ассемблере.
Код:
function Random: extended;
const two2neg32: double = 1/$100000000; // 2^-32
asm
   IMUL EDX,RandSeed,$8088405
   INC EDX
   MOV RandSeed,EDX
   FLD QWORD PTR two2neg32
   PUSH $0
   PUSH EDX
   FILD QWORD PTR [ESP]
   ADD ESP,$4
   POP EDX
   FMULP
   FSTP TBYTE PTR Result
end;
Подробно здесь

Коды получены с помощью Delphi
С запрограммированным приветом, Неверов Евгений!
Сайт: http://newerow1989.ru
[Паскаль] [Delphi]

Последний раз редактировалось newerow1989; 06.03.2017 в 08:22.
newerow1989 вне форума Ответить с цитированием
Старый 06.03.2017, 08:56   #2
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

newerow1989
Я бы всё по другому сделал. Меньше чисел больше теории.
Откуда взялось число $8088405? Каким образом оно получается?

Цитата:
Сообщение от newerow1989 Посмотреть сообщение
то мы получим одинаковый набор случайных чисел.
Слово случайный тут лишнее, набор уже неслучайный.
Наверно лучше рассказать как это можно использовать в космических игрушках для генерации случайных планет которые будут разными на разных картах и одинаковые при каждом запуске игры.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 06.03.2017, 09:03   #3
newerow1989
Я самый любопытный
Участник клуба
 
Аватар для newerow1989
 
Регистрация: 24.07.2012
Сообщений: 1,945
По умолчанию

Цитата:
Сообщение от Pavia Посмотреть сообщение
Откуда взялось число $8088405? Каким образом оно получается?
Взялось из Delphi. Это константа.
Безымянный.png
С запрограммированным приветом, Неверов Евгений!
Сайт: http://newerow1989.ru
[Паскаль] [Delphi]
newerow1989 вне форума Ответить с цитированием
Старый 06.03.2017, 09:36   #4
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Константа ПГСЧ подбирается так что-бы последовательность чисел не повторялась по кругу как можно дольше. Процесс подбора и альтернативные варианты описаны у Кнута в книге "Искусство программирования".
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 07.03.2017, 12:36   #5
kvitaliy
Участник клуба
 
Регистрация: 17.05.2011
Сообщений: 1,660
По умолчанию

Тогда уж ГПСЧ (Генератор псевдослучайных чисел)
kvitaliy вне форума Ответить с цитированием
Старый 07.03.2017, 13:47   #6
Arigato
Высокая репутация
СуперМодератор
 
Аватар для Arigato
 
Регистрация: 27.07.2008
Сообщений: 16,213
По умолчанию

Статья опубликована на сайте клуба: Генератор псевдо-случайных чисел (ПСЧ). Как образуются случайные числа?
Arigato вне форума Ответить с цитированием
Старый 23.04.2017, 13:02   #7
newerow1989
Я самый любопытный
Участник клуба
 
Аватар для newerow1989
 
Регистрация: 24.07.2012
Сообщений: 1,945
По умолчанию

Здесь тоже кто-то опубликовал: https://newscentral.exsees.com/item/...ff89bdaa5f51bf
С запрограммированным приветом, Неверов Евгений!
Сайт: http://newerow1989.ru
[Паскаль] [Delphi]
newerow1989 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
генератор случайных чисел с++ Сергей.Ш Общие вопросы C/C++ 18 25.07.2015 22:09
генератор случайных чисел Nicolas_46 Microsoft Office Excel 9 03.12.2012 14:35
C++ как сделать что бы генератор случайных чисел генерировал, но выводил только одно число RBIT Помощь студентам 3 15.10.2012 22:13
Генератор случайных чисел remont_it, C++ Builder 1 12.05.2012 21:11
Генератор случайных чисел psychopat Общие вопросы Delphi 11 18.02.2009 10:39