
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.171] |
![]() |
|
Сообщ.
#1
,
|
|
|
Часто в процессе написания программ возникают такие ситуации, когда вам в определённую числовую переменную (real, word или другие) нужно занести любое число. Вам нужно, чтобы число было случайным. И при каждом запуске программы было разным. Иногда бывает, что нужно ещё наложить ограничения на диапазон, в котором может быть значение этого числа. Специально для таких случаев в паскале есть две команы: Random и Randomize.
Классическим примером такой задачи (где нужны такие числа) может быть пример: Задача: сгенерировать массив из 10 элементов типа byte, заполнить его случайными значениями. Такая или подобная задача - нередкое явление на первом курсе университетов, или в старших классах школ. Сначала рассмотрим команду Random Это функция. Она возвращает случайное число. Вот синтаксис: function Random[(<диапазон значений>)]:<тот же тип, к какому присваивается>; Параметр <диапазон значений> может быть, а может и не быть. Если он будет, то его нужно обрамлять в круглые скобки, как и любые параметры процедур. Например a:=random(100); {С параметром <диапазон значений> - диапазон задан как 100} b:=random; {Без параметра <диапазон значений>} Если присутствует диапазон, то результатом будет обязательно целое число. Если его нет, то результатом будет вещественное (не целое) число в диапазоне [0..1]. Может быть напирмер 0.3, или 0.0001. Диапазоном значений может быть любая константа, либо переменная. Но значение диапазона не должно в BP7.x превышать число 65535 и не должно быть меньше 0, тоесть диапазон это число типа word. Можно вписать туда и переменную типа byte, или Longint. И тогда паскаль сперва преобразует значение этой переменной к типу word, а затем только укажет, что это диапазон. Для LongInt следует следить, чтобы значение не вышло за допустимые рамки. Иначе программа завершится с ошибкой. Но как интерпретировать (понимать) диапазон? если мы пишем к примеру так: a:=random(n); то командой будет сгенерировано любое число в диапазоне [0..n-1]. Например написав a:=random[10] мы получим в "а" любую цифру от 0 до 9 включительно. Но не 10. Рассмотрим задачу с условием: сформировать в переменной А типа word случайное целое число в диапазоне от 102 до 3009. Как нам нужно поступить? Сразу ясно, что просто random'ом не обойдёшься. Эта команда генерирует числа от 0, а нам нужно чтобы были от 102. Ну это не сложно. Если к сгенерированному числу прибавить 102, то все числа будут не меньше чем 102, ведь так ? В нашем случае это можно записать так: А:=102+random(... Какой теперь диапазон указать ? если мы укажем 3009, то мы получим любое число от 102+0=102 до 102+3009-1=3110. Поэтому диапазон должен быть меньше на 102-1. Написав A:=102+random(3009-(102-1)) мы получим числа от 102+0=102 до 102+(3009-(102-1))-1)= Если команда random используется без параметров, то результатом всегда будет вещественное число. Поэтому нельзя присваивать значения такого random'а целым числам. Команда Randomize Чтобы понять смысл этой команды, нужно знать, как работает команда random. Она генерирует случайное число. Но ведь компьютер это цифровая машина, и случайностей в ней быть не может. Поэтому даже кажущееся нам случайным число на самом деле является не случайным (говорят псевдослучайное). При генерации случайных чисел используется специальная формула. Она при каждом своём вызове берёт случайное число из очень длинной цифровой последовательности (например нескольких миллионов чисел). Эти числа генерируются формулой. И каждый раз берётся следующее. При запуске программы сбрасывается счётчик текущего числа в последовательности. И поэтому всегда формула генерирующая псевдослучайные числа в новой программе начинает с начала последовательности. И значит запустив два раза одну и ту же программу мы сможем получать псевдослучайные числа. Они будут относительно друг друга случайны. Но их последовательность всегда будет одинаковой. Например for p:=1 to 10 writeln(random(100)); даст 10 случайных чисел от 0 до 99. Но запустив ещё раз эту программу мы получим те же 10 случайных чисел. Числа случайны. Но они всегда одинаково идут друг за другом %) Для разрешения сложившейся ситуации была придумана команда randomize. В момент её запуска счётчик, указывающий на текущее число в длинной последовательности случайных чисел устанавливается равным колличеству миллисекунд, прошедьших от полуночи сегоднешнего дня. Ясно, что в разные моменты времени это количество удет разным. А значит и случайные числа будут другими. И поэтому если указать перед random команду randomize, то сначала установится начало последовательности случайных чисел, а потом команда random будет их брать одну за другой. В программировании принято говорить, что команда randomize инициализирует генератор случайныx чисел |
Сообщ.
#2
,
|
|||
|
Забыл расcказать что вместо того, чтобы юзать randomize можно самому инициализировать генератор случайных числел, присвоив значение переменной RandSeed
Инфа из русского Help'a к BP Добавлено в И ещё вопрос который меня самого долгое время интересовал: Как самому написать функцию аналогичную random? ![]() |
Сообщ.
#3
,
|
|||
|
Этому нас на военной кафедре учили :) Нужно взять 2 больших простых числа A и B, точные значения для 16 бит не помню :(, завести переменную randseed:longint, инициализировать ее, а дальше получать новое число как (A*randseed+B) mod 2^32, unsigned, апдейтишь randseed вычисленным значением, после чего "делай с ним что хочешь"(с) random(x) реализуется как newrandom() mod x, а random есть newrandom()/(1 shl 32) :) |
Сообщ.
#4
,
|
|||
|
Ну как же ? %) Как любит говорить vot, а посмотреть на форуме религия не позволяет ? %) Смотри про это тут: http://pascal.sources.ru/math/index.htm Там довольно много всего %) |