RandSeed — Переменная Delphi

Генератор псевдо-случайных чисел (ПСЧ). Как образуются случайные числа?

Posted by obzor under Delphi, Статьи

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

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

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

2. Как работает функция Random?

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

Согласно этой функции, последовательность чисел зависит от переменной RandSeed. Но, если значение переменной RandSeed будет всегда одинаковым, то мы получим одинаковый набор случайных чисел.
Еще одна особенность заключается в том, что переменная RandSeed всегда изменяется при вызове функции Random, т.е. устанавливает генератор случайного числа на следующее значение.

Напишем эту функцию на ассемблере.

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

Random и Randomize

Функция Random генерирует и возвращает случайное число. Синтаксис функции следующий:

Функция возвращает случайное число большее или равное 0 и строго меньше L (то есть L не входит в диапазон возвращаемых значений). Если параметр опущен (последний вариант из трёх приведённых выше), то возвращается вещественное число между 0 и 1 (0 включительно, 1 не входит в диапазон возвращаемых значений).

Математически это можно записать так:

ПРИМЕЧАНИЕ
FreePascal использует в процедуре Random имитацию случайностей Мерсенна Твистера. Эта реализация имеет большее статистическое распределение, чем, например, алгоритм Линейного Конгруэнтного генератора, но работает значительно медленнее, чем последний. Если скорость выполнения программы критична, то должны быть рассмотрены альтернативные генераторы случайных чисел.

Процедура Randomize в Паскале запускает генератор случайных чисел. Синтаксис:

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

Как запустить генератор случайных чисел в Паскале

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

ВАЖНО!
Перед использованием функции Random надо обязательно вызвать процедуру Randomize, чтобы запустить генератор случайных чисел. Иначе функция Random будет возвращать НЕ случайное число.

Процедура Randomize вызывается ТОЛЬКО ОДИН РАЗ в начале программы. Типичная ошибка новичков заключается в том, что они вызывают Randomize перед каждым вызовом Random. Этого делать не надо.

Что такое Randseed

Давайте сначала попробуем не использовать процедуру Randomize. Например, так:

В этом примере функция Random будет возвращать какое-то значение, но оно НЕ будет случайным числом. Сколько бы раз вы не запускали программу, она всегда будет выводить одинаковые числа.

В моём случае это были числа 54 и 59. В вашем случае это могут быть другие числа, но суть не в этом, а в том, что они будут всегда одинаковыми.

Теперь попробуем сделать так:

Теперь числа будут другими. В моём случае 69 и 7. Правда, они тоже не будут изменяться, то есть не будут случайными.

Однако эти числа изменились. Потому что мы изменили значение глобальной переменной Randseed.

Переменная Randseed — это глобальная предопределённая переменная в FreePascal. Она также есть и в Делфи. Так что всё сказанное будет справедливо и для Делфи.

Эта переменная задаёт начальное значение для генератора случайных чисел. Опираясь на это значение функция Random генерирует случайное число. Но, если значение переменной Randseed будет всегда одинаковым, то никаких случайных чисел мы не получим.

Поэтому при запуске программы надо хотя бы один раз вызвать процедуру Randomize, которая устанавливает начальное значение переменной Randseed, получая системное время и из этих данных формируя значение для переменной Randseed.

Так как программа запускается в какое-то случайное время, то и значение переменной Randseed будет случайным. А, следовательно, и функция Random будет возвращать случайные значения.

Давайте попробуем написать свою процедуру Randomize. Она может быть, например, такой:

Я не буду в подробностях разъяснять работу процедуры DecodeTime. Скажу только, то она возвращает, час, минуту, секунду и миллисекунду текущего времени компьютера. Мы используем миллисекунду, значение которой и присваиваем переменной Randseed.

Можете попробовать использовать эту процедуру вместо стандартной процедуры Randomize и убедиться, что функция Random возвращает случайные значения. Не забудьте подключить к программе модуль SysUtils, в котором объявлена процедура DecodeTime, иначе программа не откомпилируется.

ПРИМЕЧАНИЕ
Исходя из того, что процедура Randomize задаёт начальное значение переменной Randseed на основе текущего времени компьютера, можно предположить, что, например, если запустить программу сегодня в 12:00:00 и завтра в это же время, то функция Random вернёт одинаковые числа.

К сожалению, проверить это очень трудно, так как запустить программу в одно и то же время с точностью до миллисекунды будет практически невозможно.

Почему randseed (randomize) не инициализируется по умолчанию?

Почему randseed переменная используется для случайного числа, которое мы должны инициализировать OURSELF по телефону randomize не по крайней мере, инициализируются по умолчанию, Дельфы при запуске программы? Без этой жизненно важной инициализации (пользователь Ex забыл вызвать рандомизацию), случайный выход полностью предсказуем. Мне просто интересно, есть ли у них причина такого поведения.

Илон Маск рекомендует:  Повторение фона по горизонтали

Ваша точка имеет смысл. Однако аналогичный аргумент можно сделать и для сотни других инициализаций, которые можно было бы удобно сделать для вас при запуске, если вы выполняете программу.

Поскольку Delphi является языком общего назначения, он не должен делать никаких предположений о том, что вы хотите сделать для своего кода. Заселение рандомизатора занимает несколько вычислительных циклов, равно как и все другие инициализации, как бы они ни были желательными и разумными, они могут появляться для вашего случая использования.

Что касается этого конкретного случая: есть сценарии, которые можно себе представить, где нужно, чтобы рандомизатор посеял, скажем, системное время, чтобы иметь повторяемый набор, если числа для тестов. Разумеется, удобство имеет смысл для 99 из ста случаев, но не для всех.

Delphi 7 команда Random

14.06.2010, 20:58

Random в Delphi
Добрый день,помогите пожалуйста написать программу Random чисел с выбором диапазона чисел и.

Delphi Random и ProgressBar
Первую программу пишу на делфи, до работал в Pascal, так что простите если вопрос слишком глупый.

Четырехзначное число в Random (Delphi)
Как записать в random, чтобы число было четырехзначное? Помогите школьнику, пожалуйста.

Не работает команда через cmd на Delphi
Здравствуйте. Не находит файл и не переименовывает через командную строку через приложение.

Какая команда в delphi?
Доброго времени суток, начал думать над программой, суть в том что надо чтобы при нажатии на одном.

Функция Random и Процедура Randomize в Pascal.

В чем заключается вопрос: Что такое функция Random() и процедура Randomize в языке Pascal. Как это работает?

Сложность : легкая .

И так что такое random и randomize в pascal ?

Randomize — это процедура которая используется в Паскаль для включения генератора случайных чисел. Функция Random определяет диапазон случайных чисел. Процедура Randomize и функция Random очень часто используются для демонстрации работы массивов в Паскаль.

Т.е. функция random возвращает нам число.

И тут у нас переменная a может равняться числам от 0 до 9, не 10.

Если мы хотим вывести числа от 0 до 1, то мы пишем следующее :

Т.е. random без всего.

Бывают случаи когда хочется иметь промежуток(диапазон) чисел. Допустим от -23 до 5, как его задать ?

Для начала мы складываем 23 и 5 без учета знаков и прибавляем 1(всегда) , у нас будет 29. Теперь пишем

Но это вернет нам числа от 0 до 28, теперь просто надо вычесть 23, не учитывая знаков. Так для промежутка c отрицательными числами.

С двумя положительными числами всё наоборот, сначала вычитаем из второго первое и прибавляем 1, мы получаем число, затем к нему прибавляем первое число :

Так же есть формула для всех случаев:

Т.е. если нам нужен диапазон отрицательных чисел, например от -5 до -10, то мы пишем:

В основном random и randomize в pascal используются вместе. Если использовать random отдельно, то у нас будут случайные числа постоянно одинаковы.

Допустим у нас есть код :

И при запуске программы у нас выведется допустим 3. И если мы запустим заново, то у нас снова выведется 3 и так при каждом запуске.

Для этого и используется randomize, чтобы числа не повторялись :

Если мы это напишем, то у нас функция random каждый раз при запуске программы будет выдавать разные числа.

Функции и процедуры Delphi. Справочник.

Описание
Процедура инициализирует генерацию случайных чисел со случайного значения, используя текущее значение системного времени.
Если не инициализировать генератор случайных чисел с помощью данной процедуры, то при каждом запуске программы будет генерироваться одна и та же последовательность чисел. Для генерации определенной последовательности, необходимо системной переменной RandSeed: LongInt присвоить конкретное значение.

Генератор псевдо-случайных чисел (ПСЧ). Как образуются случайные числа?

Posted by obzor under Delphi, Статьи

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

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

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

2. Как работает функция Random?

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

Согласно этой функции, последовательность чисел зависит от переменной RandSeed. Но, если значение переменной RandSeed будет всегда одинаковым, то мы получим одинаковый набор случайных чисел.
Еще одна особенность заключается в том, что переменная RandSeed всегда изменяется при вызове функции Random, т.е. устанавливает генератор случайного числа на следующее значение.

Напишем эту функцию на ассемблере.

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

RandSeed — Переменная Delphi

Данные в компьютере можно рассматривать как ячейки памяти, имеющие свои имена (идентификаторы). Все данные в программе на языке Delphi должны быть описаны до их первого использования. И компилятор следит, чтобы в программе они использовались в соответствии с этим описанием, что позволяет избежать ошибок.

Илон Маск рекомендует:  Что такое код ibase_query

Любая величина в Delphi может быть постоянной или переменной. Её имя (идентификатор) может состоять из комбинации латинских букв, цифр и знака подчёркивания, и начинаться не с цифры. При этом регистр символов значения не имеет.

Место описания данных в программе — вне логических блоков begin / end. В модуле перед ключевым словом implementation есть блок описания:

Именно здесь, начиная со следующей строки, удобно объявлять глобальные переменные и константы. Как видим, одна (Form1) уже есть!

Команда объявления переменных в языке Delphi:

var имя_переменной : тип_переменной ;

Слово var — ключевое. Именем может быть любой идентификатор, если он не был описан ранее и не является одним из ключевых или зарезервированных слов языка Delphi. Если нужно описать несколько переменных одного типа, то их перечисляют, отделяя запятой:

Если несколько описаний следуют друг за другом, то ключевое слово var повторно можно не указывать:

Постоянную величину иначе называют константой. Конечно, в программе можно использовать числа и строки непосредственно: 3.1415 или ‘Это значение числа пи’ , но иногда удобнее присвоить их идентификатору. Описание констант аналогично описанию переменных, но используется ключевое слово const, за именем идентификатора следует тип, затем знак равенства и его значение. Причём тип константы допускается не указывать:

const pi= 3.1415 ;
ZnakPi : String = ‘Это значение числа пи’ ;

К слову, константа Pi встроенная в Delphi, то есть для того чтобы использовать в Delphi число 3,1415. в расчётах, нужно просто присвоить встроенную константу Pi переменной типа Real или просто использовать непосредственно в выражениях.

Теперь пришло время узнать о типах данных, используемых в Delphi. Прежде всего это строки и числа.

Строкой называется последовательность символов, заключённая в одиночные кавычки:
‘это текстовая строка’ Если текст должен содержать сам символ кавычки, то его надо повторить дважды:
‘это » — символ одиночной кавычки’ Строка может быть и пустой, не содержащей символов. Тогда она состоит из двух идущих друг за другом без пробела кавычек. Естественно, строка может состоять и только из одних пробелов.
Самый популярный строковый тип — String. Строка типа String может содержать переменное количество символов объёмом до 2 Гбайт. Если нужно ограничить размер строки фиксированным значением, то после ключевого слова String в квадратных скобках указывается число, определяющее количество символов в строке: String[50]. Более полно работа со строками Delphi описывается далее.
Одиночный символ имеет тип Char и записывается в виде знака в одиночных кавычках: ‘a’. Есть символы, которые на экране отобразить невозможно, например, символ конца строки (равен #13), символ переноса строки (равен #10). Такие символы записываются в виде их числового кода (в кодировке ANSI), перед которым стоит знак #. Например, #0.
Наконец, существуют так называемые нуль-терминированные строки. Отсчёт символов в таких строках начинается с нуля, а заканчивается символом с кодом (#0). Такие строки имеют тип PChar.

Числа бывают целые и дробные.
В следующей таблице перечислены стандартные типы целых чисел и соответствующие им дипазоны допустимых значений.

Integer -2147483648 .. +2147483647
Cardinal 0 .. 4294967295
Shortint -128 .. +127
Smallint -32768 .. +32767
Int64 -2 63 .. +2 63 -1
Byte 0 .. +255
Word 0 .. +65535
Наиболее удобным для использования в программах является тип Delphi Integer. Другие целые типы используются для уменьшения места, занимаемого данными в памяти компьютера.

Дробные числа имеют дробную часть, отделяемую десятичной точкой. Допускается использование символа e (или E), за которым следует число, указывающее, что левую часть нужно умножить на 10 в соответствующей степени: 5e25 — пять умножить на десять в двадцать пятой степени.
Ниже приведены стандартные типы дробных чисел и соответствующие им диапазоны допустимых значений. Для большинства типов указан диапазон положительных значений, однако допустимым является аналогичный диапазон отрицательных значений, а также число .

Real 5*10 -324 .. 1.7*10 308
Real48 2.9*10 -39 .. 1.7*10 38
Singl 1.5*10 -45 .. 3.4*10 38
Double 5*10 -324 .. 1.7*10 308
Extended 3.6*10 -4951 .. 1.1*10 4932 -1
Comp -2 63 .. +2 63 -1
Currency 922337203685477.5807
Наиболее удобным для использования в программах является тип Delphi Real. Ему эквивилентен тип Double, но в будущем это может быть изменено. Вычисления с дробными числами выполняются приближённо, за исключением типа Currency (финансовый), который предназначен для минимизации ошибок округления в бухгалтерских расчётах.

Следующим типом данных является логический Boolean, состоящий всего из двух значений: True (Истина) и False (Ложь). При этом True > False.

Теперь, используя компоненты, их свойства и события, вводя собственные переменные, можно конструировать программы, содержащие вычисления. Осталось узнать, как вычисленное значение вывести на экран.
Про консольные программы я здесь не говорю! А в нормальных оконных Windows-приложениях это значение нужно поместить в какой-нибудь компонент, имеющий свойства Text или Caption. Это, например, такие компоненты как Label и Edit, да и сама Форма имеет свойство Caption, куда тоже можно выводить информацию. Однако, в Delphi информацию перед выводом, как правило, необходимо преобразовывать. Так как присвоение возможно только между переменными одного типа, то такая программа (не пытайтесь её исполнять):

var A, B, C: Integer ;
begin
A := 5 ;
B := 10 ;
C := A+B ;
Label1.Caption := C ;
end ;

Илон Маск рекомендует:  Что такое код realpath

вызовет ошибку, так как свойство Caption имеет текстовый тип String, а использованные переменные — цифровой тип Integer. Значит, нужно преобразовать значение переменной C в текстовый тип. Для этого есть встроенная функция IntToStr. Строка в нашей «программе», вызывавшая ошибку, должна выглядеть так:

Такая программа, кроме показа числа 15, ни на что не способна. Мы должны научиться вводить в программу другие числа. Используем компоненты Edit. Введённые числа будут содержаться в свойстве Text этих компонентов. Расположим на форме два компонента Edit, один компонент Label и кнопку Button, по нажатию на которую и будем проводить вычисления. В компоненты Edit1 и Edit2 будем вводить числа для суммирования. Чтобы переместиться в редактор кода, щёлкнем дважды по нашей кнопке Button1. Мы попадём прямо в сформированную для нас средой Delphi заготовку обработчика нажатия на кнопку, непосредственно между операторами begin и end. Напишем такой простой код:

procedure TForm1.Button1Click(Sender: TObject);
var A, B, C: Integer; //Не забудьте описание переменных
begin
//Начало кода:
A := Edit1.Text;
B := Edit2.Text;
C := A+B;
Label1.Caption := IntToStr(C);
//Конец кода
end ;

При попытке исполнить этот код Delphi покажет ошибки по аналогичной причине — переменные A и B имеют цифровой тип Integer, а свойство Text — текстовый тип String. Исправить ошибки поможет встроенная функция StrToInt, выполняющая обратное преобразование — текст в целое число. Операторы присвоения переменным A и B должны выглядеть так:

A := StrToInt(Edit1.Text);
B := StrToInt(Edit2.Text);

В данном случае переменные A, B, C использовались для наглядности. Можно обойтись одной строчкой:

Аналогично, имеются функции и для преобразования в строку и обратно действительных чисел c плавающей (Floating англ.) запятой, имеющих тип Real. Для преобразования в строку — FloatToStr, обратно — StrToFloat.
Часто результаты вычислений, имеющие тип Delphi Real, имеют после запятой длинный «хвост» цифр. При выводе такой переменной в текстовом виде необходимо ограничить количество цифр после запятой. Как это можно сделать, описывается также в Уроке Delphi Работа со строками Delphi.

Функция Random и Процедура Randomize в Pascal.

В чем заключается вопрос: Что такое функция Random() и процедура Randomize в языке Pascal. Как это работает?

Сложность : легкая .

И так что такое random и randomize в pascal ?

Randomize — это процедура которая используется в Паскаль для включения генератора случайных чисел. Функция Random определяет диапазон случайных чисел. Процедура Randomize и функция Random очень часто используются для демонстрации работы массивов в Паскаль.

Т.е. функция random возвращает нам число.

И тут у нас переменная a может равняться числам от 0 до 9, не 10.

Если мы хотим вывести числа от 0 до 1, то мы пишем следующее :

Т.е. random без всего.

Бывают случаи когда хочется иметь промежуток(диапазон) чисел. Допустим от -23 до 5, как его задать ?

Для начала мы складываем 23 и 5 без учета знаков и прибавляем 1(всегда) , у нас будет 29. Теперь пишем

Но это вернет нам числа от 0 до 28, теперь просто надо вычесть 23, не учитывая знаков. Так для промежутка c отрицательными числами.

С двумя положительными числами всё наоборот, сначала вычитаем из второго первое и прибавляем 1, мы получаем число, затем к нему прибавляем первое число :

Так же есть формула для всех случаев:

Т.е. если нам нужен диапазон отрицательных чисел, например от -5 до -10, то мы пишем:

В основном random и randomize в pascal используются вместе. Если использовать random отдельно, то у нас будут случайные числа постоянно одинаковы.

Допустим у нас есть код :

И при запуске программы у нас выведется допустим 3. И если мы запустим заново, то у нас снова выведется 3 и так при каждом запуске.

Для этого и используется randomize, чтобы числа не повторялись :

Если мы это напишем, то у нас функция random каждый раз при запуске программы будет выдавать разные числа.

RandSeed — Переменная Delphi

125 просмотра

1 ответ

3103 Репутация автора

Почему randseed переменная, используемая для случайного числа, которое мы должны инициализировать сами, вызывая, по крайней мере, по умолчанию randomize не инициализируется delphi при запуске программы? Без этой жизненно важной инициализации (бывший пользователь забудет вызвать randomize), случайный вывод полностью предсказуем. Мне просто любопытно, есть ли причина для такого поведения .

Ответы (1)

4 плюса

1946 Репутация автора

Ваша точка зрения имеет смысл. Тем не менее, аналогичный аргумент может быть приведен для сотен других инициализаций, которые удобно выполнить для вас при запуске программы.

Поскольку Delphi является языком общего назначения, он не должен делать никаких предположений относительно того, что вы хотите, чтобы ваш код делал. Заполнение рандомизатора занимает несколько вычислительных циклов, как и все другие инициализации, какими бы желательными и осмысленными они не казались для вашего случая использования.

Что касается этого конкретного случая: есть сценарии, которые можно себе представить, когда нужно, чтобы рандомизатор отбирался, скажем, из системного времени, чтобы иметь повторяемый набор, если числа для тестов. Конечно, удобство имеет смысл в 99 из ста случаев, но не во всех.

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL