Как MathRand() генерирует значения?

 

Расскажите, плз,  как MathRand() получает значения.

Можно ли ожидать равномерное распределение MathRand() в заявленном диапазоне?

 

Многократно обсуждалось на четвёрочном форуме. Поиск по слову MathRand даёт более 15 страниц результатов

Например, эти темы:

https://www.mql5.com/ru/forum/123337

https://www.mql5.com/ru/forum/111855

https://www.mql5.com/ru/forum/111974

https://www.mql5.com/ru/forum/125667 

Генерация равномерно распределенных случайных чисел (0,1) - MQL4 форум
  • www.mql5.com
Генерация равномерно распределенных случайных чисел (0,1) - MQL4 форум
 
yu-sha:

Расскажите, плз,  как MathRand() получает значения.

Можно ли ожидать равномерное распределение MathRand() в заявленном диапазоне?

По моему, можно провести тест на распределение, но как его делать уже не помню.

На php как-то давно проверял.

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

Или можно например найти кол-во одинаковых чисел для грубой оценки.

Сгенерируйте пару сотен чисел и запишите в файл, потом постройте график хотя бы экселем.

 

stringo

Не осилил все предложенные для прочтения ссылки))

Глядя на количество сообщений и состав участников дискуссии, сделал вывод:

- пользоваться MathRand() можно смело

- если не хватает "разрешения" 0..32767, то можно брать MathRand()*MathRand(), - распределение не станет сильно "перекошенным" в ту или иную сторону

mrProF,

 Грубую оценку провести несложно

int A[32768] ;

for (int i=0; i<100000000; i++)

  A[MathRand()]++; 

но зачем?

для моих целей достаточно комментария разработчиков 

 
yu-sha:

для моих целей достаточно комментария разработчиков 

Разработчики не разрабатывали самостоятельно MathRand, а просто реализовали трансляцию вызовов напрямую к функциям CRT srand и rand.

Для общего употребления годится.

 
А если хочется "огого" то https://www.mql5.com/ru/forum/123337/page16 самый нижний пост.
Генерация равномерно распределенных случайных чисел (0,1) - MQL4 форум
  • www.mql5.com
Генерация равномерно распределенных случайных чисел (0,1) - MQL4 форум
 
gumgum:
А если хочется "огого" то https://www.mql5.com/ru/forum/123337/page16 самый нижний пост.

мне нужно в алгоритмах нечеткой логики случайно сдвигать веса

главное, чтобы не было постоянных "завалов" в какую-то одну сторону 

за "ого-го" спасибо, конечно, но в моем случае это излишне )) 

 

на счет

"- если не хватает "разрешения" 0..32767, то можно брать MathRand()*MathRand(), - распределение не станет сильно "перекошенным" в ту или иную сторону"

это я погорячился ...

матожидание сместится влево от середины диапазона (подозреваю, что к 1/4 * 32768^2 , но уже ни в чем не уверен)

в общем, мое утверждение было неверным 

 
yu-sha:

на счет

"- если не хватает "разрешения" 0..32767, то можно брать MathRand()*MathRand(), - распределение не станет сильно "перекошенным" в ту или иную сторону"

это я погорячился ...

матожидание сместится влево от середины диапазона (подозреваю, что к 1/4 * 32768^2 , но уже ни в чем не уверен)

в общем, мое утверждение было неверным 

чмсло ддиапазона  [0, (2^rstep)-1] 

long ranD(int rstep)
{
long div=1;
long r=0; 
   for(int i=1;i<=rstep;i++)
   {
   if(MathRand()+1>16383.5){if(i==1){r=1;}else{r+=div;}}
   div=div*2;
   }
return(r);
}

Вместо long можно int или double или ulong.

 

gumgum,

  rstep  [0, 2^rstep-1]  - не понял что это за параметр

 

Вопрос:

double переменную нужно изменять случайным образом с точностью, скажем, до 8-го знака после запятой

MathRand()/32768 даст шаг 0.00003 - мало

Как получить равномерно распределенную на  (0..1) случайную величину с дискретностью 0.00000001 с помощью MathRand() ?

 
yu-sha:

gumgum,

  rstep  [0, 2^rstep-1]  - не понял что это за параметр

 

Вопрос:

double переменную нужно изменять случайным образом с точностью, скажем, до 8-го знака после запятой

MathRand()/32768 даст шаг 0.00003 - мало

Как получить равномерно распределенную на  (0..1) случайную величину с дискретностью 0.00000001 с помощью MathRand() ?


при rsign=1 (-1,1)  при rsign=0 (0,1)

double ranD(int rsign,int rstep)
{
double div=2;
double r=0; 
   for(int i=1;i<=rstep;i++)
   {
   if(MathRand()+1>16383.5){r+=1/div;}
   div=div*2;   
   }
      if(rsign==1)
         {
         r=2*r-1;
         }
return(r);
}

 rstep это степень 

Причина обращения: