Получение случайного числа средствами 1С (пример функции)

Публикация № 57305

Разработка - Практика программирования

17
Принцип основан на том, что от момента получения случайного числа до наступления следующей секунды программа увеличит счетчик каждый раз на разное количество.
функция генерирует случайное (или псевдослучайное?) число от НачЧисло до КонЧисло
Функция СлучайноеЧисло(НачЧисло = 0,КонЧисло = 1,флЦелое = 0)
ТекВремя =ТекущееВремя();
СлЧисло = 0;
Пока ТекущееВремя() =ТекВремя Цикл

СлЧисло =СлЧисло + 1;
	

КонецЦикла;
СлЧисло =Число(Прав("000" +СлЧисло, 3)) / 1000;

// число от 0 до 0.999 

СлЧисло =НачЧисло + (КонЧисло -НачЧисло) *СлЧисло; 

// число от НачЧисло до КонЧисло
Возврат ?флЦелое = 1,Окр(СлЧисло, 0),СлЧисло);
КонецФункции 
17

См. также

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо
1. PowerBoy 2904 03.10.08 07:07 Сейчас в теме
(0) Я даже без теста вижу, что спектр сдесь будет неоднородный - т.е. определённые числа будут выпадать чаще.
2. Abadonna 3831 03.10.08 07:17 Сейчас в теме
Уж лучше цепляться за _GetPerformanceCounter(), чем за ТекущееВремя()
3. noblekey 98 03.10.08 08:35 Сейчас в теме
Можно еще так

Функция ПолучитьСлучайноеЧисло(Мин,Макс)

//вместо Randomize
Для н = 1 По 100 Цикл
Уник = Новый УникальныйИдентификатор;
КонецЦикла;

//генерируем GUID
Уник = СокрЛП(Новый УникальныйИдентификатор);

//оставляем только цифры
Уник = СтрЗаменить(Уник,"-","");
Уник = СтрЗаменить(Уник,"a","");
Уник = СтрЗаменить(Уник,"b","");
Уник = СтрЗаменить(Уник,"c","");
Уник = СтрЗаменить(Уник,"d","");
Уник = СтрЗаменить(Уник,"e","");
Уник = СтрЗаменить(Уник,"f","");

//знаменатель должен иметь такое же количество нулей + 1
Знаменатель = 10;
Для н = 2 По (СтрДлина(СтрЗаменить(Уник,Символы.НПП,""))) Цикл
Знаменатель = Знаменатель * 10;
КонецЦикла;

Случ = Число(Уник) / Знаменатель; //здесь получается дробное случайное число от 0 до 1

//преобразуем его в случайное число из заданного интервала, округляем до целого
ЧислоИзИнтервала = Мин(Макс(Окр(Мин + (Макс-Мин)*Случ),Мин),Макс);

Возврат ЧислоИзИнтервала;

КонецФункции
Andreyyy; user1038570; rpgshnik; feel_deep; rayastar; sanfoto; V.Nikonov; artbear; +8 Ответить
5. kitt 325 03.10.08 10:54 Сейчас в теме
(3) можно еще так:
Код
ГСЧ = Новый ГенераторСлучайныхЧисел(255);
Рэндом = ГСЧ.СлучайноеЧисло(0, 10000);
Показать полностью

:)
user895546; Soloist; maksa2005; Plotks2017; Shadow326; Montecrizto; v.krivenko; adhocprog; Mir-mup; DrAku1a; twin; iceser1; mix; +13 1 Ответить
16. rpgshnik 1628 12.09.16 10:26 Сейчас в теме
(5) kitt, Эта штатная какашка выдает одно и тоже число((
19. MariusUrsus 18.08.17 11:12 Сейчас в теме
(16)

Новый ГенераторСлучайныхЧисел(<НачальноеЧисло>)
Параметры:
<НачальноеЧисло> (необязательный)
Тип: Число.
Начальное число, которым инициализируется генератор случайных чисел.
Описание:
Генератор случайных чисел инициализируется начальным числом из параметра.
Последовательность случайных чисел для одного и того же начального числа будет одинакова.


нужно изменяющееся зерно задавать, например так
ГенераторСлучайныхЧисел  = Новый ГенераторСлучайныхЧисел(ТекущаяУниверсальнаяДатаВМиллисекундах());
СлучайноеЧисло = ГенераторСлучайныхЧисел.СлучайноеЧисло(0, 99);
Sintson; user811626; chubajs12; Plotks2017; ivv1970; +5 Ответить
7. artbear 1149 05.05.09 18:20 Сейчас в теме
(3) Плюсую.
Мне нужно было получить несколько случайных чисел для 8.0
Вариант из (3) помог, т.к. скорость выполнения была не важна.
9. V.Nikonov 119 17.09.11 12:08 Сейчас в теме
Может лучше малость подправленный вариант (3)
//НВЮ/ Получение Случайного Числа
//
// Параметры
//  <Мин>  - <Число> - Нижняя граница Равномерного Распределения
//  <Макс>  - <Число> - Верхняя граница Равномерного Распределения
//
// Возвращаемое значение:
//   <Число>   - Сгенерированное случайное число
//
Функция ПолучитьСлучайноеЧисло(Мин=0,Макс=100) Экспорт

//вместо Randomize 
Для н = 1 По Макс Цикл 
Уник = Новый УникальныйИдентификатор; 
КонецЦикла; 

//генерируем GUID 
Уник = СокрЛП(Новый УникальныйИдентификатор); 

//оставляем только цифры 
Уник	= СтрЗаменить(Уник,"-","");
Уник	= СтрЗаменить(Уник,Символы.НПП,"");

Случ = 0;
//знаменатель должен иметь такую же разрядность 
Знаменатель = 1; 
Для н = 1 По (СтрДлина(Уник)) Цикл
	ТекС = Сред(Уник,н,1);
	Если ТекС="a" Тогда
		Случ = Случ + Знаменатель*10;
	ИначеЕсли ТекС="b" Тогда
		Случ = Случ + Знаменатель*11;
	ИначеЕсли ТекС="c" Тогда
		Случ = Случ + Знаменатель*12;
	ИначеЕсли ТекС="d" Тогда
		Случ = Случ + Знаменатель*13;
	ИначеЕсли ТекС="e" Тогда
		Случ = Случ + Знаменатель*14;
	ИначеЕсли ТекС="f" Тогда
		Случ = Случ + Знаменатель*15;
	ИначеЕсли ТекС="1" Тогда
		Случ = Случ + Знаменатель;
	ИначеЕсли ТекС="2" Тогда
		Случ = Случ + Знаменатель*2;
	ИначеЕсли ТекС="3" Тогда
		Случ = Случ + Знаменатель*3;
	ИначеЕсли ТекС="4" Тогда
		Случ = Случ + Знаменатель*4;
	ИначеЕсли ТекС="5" Тогда
		Случ = Случ + Знаменатель*5;
	ИначеЕсли ТекС="6" Тогда
		Случ = Случ + Знаменатель*6;
	ИначеЕсли ТекС="7" Тогда
		Случ = Случ + Знаменатель*7;
	ИначеЕсли ТекС="8" Тогда
		Случ = Случ + Знаменатель*8;
	ИначеЕсли ТекС="9" Тогда
		Случ = Случ + Знаменатель*9;
	КонецЕсли;
	Знаменатель = Знаменатель * 16;
КонецЦикла; 

Случ = Случ / Знаменатель; //здесь получается дробное случайное число от 0 до 1 

//преобразуем его в случайное число из заданного интервала, округляем до целого 
ЧислоИзИнтервала = Мин(Макс(Окр(Мин + (Макс-Мин)*Случ),Мин),Макс); 

Возврат ЧислоИзИнтервала; 

КонецФункции //ПолучитьСлучайноеЧисло()
Показать
10. V.Nikonov 119 17.09.11 12:08 Сейчас в теме
Может лучше малость подправленный вариант (3)
//НВЮ/ Получение Случайного Числа
//
// Параметры
//  <Мин>  - <Число> - Нижняя граница Равномерного Распределения
//  <Макс>  - <Число> - Верхняя граница Равномерного Распределения
//
// Возвращаемое значение:
//   <Число>   - Сгенерированное случайное число
//
Функция ПолучитьСлучайноеЧисло(Мин=0,Макс=100) Экспорт

//вместо Randomize 
Для н = 1 По Макс Цикл 
Уник = Новый УникальныйИдентификатор; 
КонецЦикла; 

//генерируем GUID 
Уник = СокрЛП(Новый УникальныйИдентификатор); 

//оставляем только цифры 
Уник	= СтрЗаменить(Уник,"-","");
Уник	= СтрЗаменить(Уник,Символы.НПП,"");

Случ = 0;
//знаменатель должен иметь такую же разрядность 
Знаменатель = 1; 
Для н = 1 По (СтрДлина(Уник)) Цикл
	ТекС = Сред(Уник,н,1);
	Если ТекС="a" Тогда
		Случ = Случ + Знаменатель*10;
	ИначеЕсли ТекС="b" Тогда
		Случ = Случ + Знаменатель*11;
	ИначеЕсли ТекС="c" Тогда
		Случ = Случ + Знаменатель*12;
	ИначеЕсли ТекС="d" Тогда
		Случ = Случ + Знаменатель*13;
	ИначеЕсли ТекС="e" Тогда
		Случ = Случ + Знаменатель*14;
	ИначеЕсли ТекС="f" Тогда
		Случ = Случ + Знаменатель*15;
	ИначеЕсли ТекС="1" Тогда
		Случ = Случ + Знаменатель;
	ИначеЕсли ТекС="2" Тогда
		Случ = Случ + Знаменатель*2;
	ИначеЕсли ТекС="3" Тогда
		Случ = Случ + Знаменатель*3;
	ИначеЕсли ТекС="4" Тогда
		Случ = Случ + Знаменатель*4;
	ИначеЕсли ТекС="5" Тогда
		Случ = Случ + Знаменатель*5;
	ИначеЕсли ТекС="6" Тогда
		Случ = Случ + Знаменатель*6;
	ИначеЕсли ТекС="7" Тогда
		Случ = Случ + Знаменатель*7;
	ИначеЕсли ТекС="8" Тогда
		Случ = Случ + Знаменатель*8;
	ИначеЕсли ТекС="9" Тогда
		Случ = Случ + Знаменатель*9;
	КонецЕсли;
	Знаменатель = Знаменатель * 16;
КонецЦикла; 

Случ = Случ / Знаменатель; //здесь получается дробное случайное число от 0 до 1 

//преобразуем его в случайное число из заданного интервала, округляем до целого 
ЧислоИзИнтервала = Мин(Макс(Окр(Мин + (Макс-Мин)*Случ),Мин),Макс); 

Возврат ЧислоИзИнтервала; 

КонецФункции //ПолучитьСлучайноеЧисло()
Показать
Mails79; Mir-mup; +2 Ответить
4. Shaman100M 1191 03.10.08 09:37 Сейчас в теме
Код
////////////////////////// 
// ГЕНЕРАТОР СЛУЧАЙНЫХ ЧИСЕЛ
//       Автор Сергей Нефедов
////////////////////////// 
Процедура randomize(а=0)   
    // сбрасывает генератор
    Если а=0 тогда    
        randSeed=_getPerformanceCounter();  
    Иначе
        randseed=а;  
    КонецЕсли;    
КонецПроцедуры
Функция random()    
    // выдает случайное число 0 <= rand < 1
    // интерпретация интерпритации AVB
    // выдает последовательности лучше, и работает быстрее. 
    // (не замедляется)
    // дело в том, что у него возникают очень большие числа,
    // а 1С некокорректно с ними работает (операция %)
    randSeed=(randSeed*1103515245+12345)%2147483648; 
    возврат randSeed/2147483648;
КонецФункции     
Показать полностью
6. vovan519 275 03.10.08 12:42 Сейчас в теме
(0) Ждать целую секунду? ... Долго.
8. opupety 25.04.10 23:17 Сейчас в теме
Можно просто использовать локальную переменную среды %RANDOM%
11. artly2000 09.07.13 09:33 Сейчас в теме
Автор ArtLy.
Я долго искал возможность создания генератора случайных чисел в 1С7.7 и вот свершилось. Разброс чисел по оценке - отлично. Используется средствами VBScript

//Глобальный модуль
Функция _СлучайноеЧислоVBA(VBA, N, ВыдаватьНоль = 0) Экспорт 
 Если ВыдаватьНоль = 0 Тогда
  N = N + 1;
 КонецЕсли;	
 VBA.Language = "VBscript";  
 VBA.AddCode("
 |Function GetRND(x)
 |R = Int(0 + (Rnd() * x)) 
 |GetRND = R
 |End Function
 |");
 Результат=VBA.Modules("Global").CodeObject.GetRND(N); 
 Если Результат = 0 Тогда
  Если ВыдаватьНоль = 0 Тогда
    Результат = 1;
  КонецЕсли;
 КонецЕсли;
 Возврат Результат;
КонецФункции
Показать

//Где-то в модуле формы
Процедура ПриОткрытии()
  VBA = СоздатьОбъект("MSScriptControl.ScriptControl"); 
  ДоЧисла = 3;
  ВыдаватьНоль = 0;    
  Для Ц = 1 По 100 Цикл
    Ранд = _СлучайноеЧислоVBA(VBA, ДоЧисла, ВыдаватьНоль);
    Сообщить(Ранд);
  КонецЦикла;		
КонецПроцедуры
Показать
17. shagua 20.12.16 18:52 Сейчас в теме
(11)
Перед вызовом Rnd для инициализации генератора случайных чисел с начальным значением на основе системного таймера воспользуйтесь оператором Randomize без указания аргументов.

Код можно переписать так (будет генерить целые от 1 до 100):

Функция СлучайноеЧислоVBA(N)
	VBA = СоздатьОбъект("MSScriptControl.ScriptControl"); 
	VBA.Language = "VBscript";  
	VBA.AddCode("
	|Function GetRND(x)
	|Randomize
	|R = Int(1   (Rnd() * x)) 
	|GetRND = R
	|End Function
	|");
	Возврат VBA.Modules("Global").CodeObject.GetRND(N); 
КонецФункции

Процедура Тест()
	Для Ц = 1 По 100 Цикл
		Ранд = СлучайноеЧислоVBA(100);
    	Сообщить(Ранд);
	КонецЦикла;        
КонецПроцедуры
Показать
12. MoonAriman 6 13.02.14 11:38 Сейчас в теме
Нам нужно было получать случайные числа в заданном диапазоне до 2-х знаков после запятой. Типовой генератор случайных чисел не может нецелые числа генерировать. Вышли из ситуации просто, следующим образом:

ГСЧ = Новый ГенераторСлучайныхЧисел;
СлучЧисло = ГСЧ.СлучайноеЧисло(НецелоеЧисло1*100, НецелоеЧисло2*100);
СлучЧисло=Окр(СлучЧисло/100,2);

Прикрепленные файлы:
13. gonkommu 26.07.15 08:55 Сейчас в теме
Может кому пригодится, генератор от 1 до 99, выручает на семерке

_tmp=СоздатьОбъект("MSScriptControl.ScriptControl");
_tmp.language="javascript";
_rand= Цел(_tmp.eval("Math.random()")*100);

Сообщить(_rand);
14. maksa2005 290 09.02.16 14:13 Сейчас в теме
ГСЧ = Новый ГенераторСлучайныхЧисел(Формат(ТекущаяДата(),"ДФ=ddMMyyyyhhmmss"));
ТС.НомерДокумента = СтрЗаменить(ГСЧ.СлучайноеЧисло(0,1000)," ","");
15. Mr.Rome 14.05.16 11:57 Сейчас в теме
Проанализировав все что тут написано - объединил в наиболее приемлемое.
Вставлять в глобальный модуль

ЗЫЖ 7.7

Функция ПолучитьСлучайноеЧисло(МаксЗН,ВыдаватьНоль = 0) Экспорт Далее

//**********************************************************************    
Функция ПолучитьСлучайноеЧисло(МаксЗН,ВыдаватьНоль = 0) Экспорт
	                    
	//Увеличиваем на единицу, т.к. функция не возвращает верхний порог
	МаксЗН = МаксЗН + 1;
	
	Скрипт=СоздатьОбъект("MSScriptControl.ScriptControl"); 
	Скрипт.language="javascript"; 
	Результат= Цел(Скрипт.eval("Math.random()")*МаксЗН); 
	  
	Если (ВыдаватьНоль = 0) и (Результат = 0) Тогда
		Пока Результат = 0 Цикл
			Результат = ПолучитьСлучайноеЧисло(МаксЗН,0)
		КонецЦикла;
	КонецЕсли;                                   
		
	Возврат Результат;
	
КонецФункции
Показать
20. User80 121 14.02.18 13:10 Сейчас в теме
Не нужно выдумывать велосипед. При создании генератора случайных чисел не задавайте начальное число и все будет работать.

ГСЧ = Новый ГенераторСлучайныхЧисел();
Рэндом = ГСЧ.СлучайноеЧисло(0, 10000);
user609158_alex.smm1493; +1 Ответить
22. НатальяАлекс 19 19.10.18 14:41 Сейчас в теме
(20) Спасибо! действительно работает!
21. kadild 30.08.18 18:26 Сейчас в теме
В синтаксис помощнике хоть и написали, что "Последовательность случайных чисел для одного и того же начального числа будет одинакова.", но почему-то не указали что это генератор не случайных чисел, а псевдослучайных. Такая функция есть почти у всех языков и они псевдослучайные.

Генератор псевдослучайных чисел, то есть устройство, которое выдает последовательность чисел, отвечающую определенным статистическим критериям случайности.

Например можно воспользоватся классов из Win (mscorlib.dll):
Rnd = СоздатьОбъект("System.Random");
Сообщить(Rnd.Next());
stas_roman; +1 Ответить
23. Cucu.ruza 28.03.19 09:29 Сейчас в теме
перем ч,м,с;
ТекущееВремя(ч,м,с);
чис=ч*ДатаЧисло(ТекущаяДата())+м*ДатаМесяц(ТекущаяДата())+с*ДатаГод(ТекущаяДата());
Сообщить(чис % 10000);

Применяется для генерации промо-кодов.
Оставьте свое сообщение