Скачать MetaTrader 5

Генератор случайных чисел в заданном диапазоне

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Они уже зарабатывают с помощью сервиса Фриланс. Зарабатывай и ты!
Murat Ishakov
1491
Murat Ishakov 2015.07.18 21:26 
Подскажите пожалуйста как создать генератор случайных чисел в заданном диапазоне, например создать 20 чисел от 0 до 1 с шагом 0.01, интересуют именно дробные числа. Заранее всем благодарен)
Victor Nikolaev
Модератор
14527
Victor Nikolaev 2015.07.18 21:29  
Murat Ishakov:
Подскажите пожалуйста как создать генератор случайных чисел в заданном диапазоне, например создать 20 чисел от 0 до 1 с шагом 0.01, интересуют именно дробные числа. Заранее всем благодарен)
Создать генератор или получить псевдослучайные числа с помощью встроенного генератора?
Andrey Dik
11353
Andrey Dik 2015.07.19 08:31  
//--- input parameters
//input double   pMin   = -12.0;
//input double   pMax   = 23.0;
//input double   pStep  = 0.03;
//input int      pCount = 20;

input double   pMin   = 0.0;
input double   pMax   = 1.0;
input double   pStep  = 0.01;
input int      pCount = 20;
//——————————————————————————————————————————————————————————————————————————————
void OnStart()
{
  double m[];
  ArrayResize(m, pCount);
  ArrayInitialize(m, 0.0);
  
  for(int i=0; i<pCount; i++)
  {
    m[i]= f_seInDiSp(f_RNDfromCI(pMin, pMax), 
                     pMin, pMax, pStep);
    Print(DoubleToString(m[i],6)); 
  } 
}
//——————————————————————————————————————————————————————————————————————————————

//——————————————————————————————————————————————————————————————————————————————
// Выбор в дискретном пространстве
double f_seInDiSp(double in, double inMin, double inMax, double step) 
{ 
  if(in <= inMin) 
    return (inMin); 
  if(in >= inMax) 
    return (inMax); 
  if(step == 0.0) 
    return (in); 
  else return (inMin + step * (double)MathRound((in - inMin) / step));
}
//——————————————————————————————————————————————————————————————————————————————

//——————————————————————————————————————————————————————————————————————————————
// Генератор случайных чисел из заданного интервала.
double f_RNDfromCI(double min, double max) 
{ 
  if(min == max) 
    return (min); 
  double Min, Max; 
  if(min > max) 
  {
    Min = max; 
    Max = min;
  }
  else 
  {
    if(min < max) 
    {
      Min = min; 
      Max = max;
    }
    else return (min);
  }
  return (double(min + ((max - min) * (double)MathRand() / 32767.0)));
}
//——————————————————————————————————————————————————————————————————————————————
Petros Shatakhtsyan
9210
Petros Shatakhtsyan 2015.07.19 09:46  
Murat Ishakov:
Подскажите пожалуйста как создать генератор случайных чисел в заданном диапазоне, например создать 20 чисел от 0 до 1 с шагом 0.01, интересуют именно дробные числа. Заранее всем благодарен)

 

Вы не очень ясно сформулировали ваш вопрос, и поэтому сейчас будут диссертацию написать на эту тему.

Если вам нужно получить случайные числа в диапазоне от 0 до 1, и 2 знака после запятой, то можно так:

      double d;

      MathSrand(GetTickCount());

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

      {

         d=(MathRand()%100)/100.0; 

         PrintFormat("%3.2f",d);

      }

Dmitry Fedoseev
42924
Dmitry Fedoseev 2015.07.19 10:09  
double r=MathRand();

r/=32768; // имеем случайное число от 0 до 1 (больше или равно 0 и меньше 1).

От 0 до 1 с шагом 0.01 никак не получается 20 чисел, их будет 100.

Значит  так:

r=NormalizeDouble(MathCeil(r*100)/100,2);
Если использовать остаток от деления, число перестает быть случайным.
Andrey Dik
11353
Andrey Dik 2015.07.19 10:40  
Dmitry Fedoseev:

От 0 до 1 с шагом 0.01 никак не получается 20 чисел, их будет 100.

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

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

Dmitry Fedoseev
42924
Dmitry Fedoseev 2015.07.19 10:44  

Обана, сюрпризик:

 

Вот код (скрипт в МТ4):

void OnStart()
  {
//---
   
double r=MathRand();

r/=32768; // имеем случайное число от 0 до 1 (больше или равно 0 и меньше 1).
r=NormalizeDouble(MathCeil(r*100)/100,2);   

Alert(r);
   
  }
Примерно на каждом 15-20 запуске скрипта выскакивает хвост.
Andrey Dik
11353
Andrey Dik 2015.07.19 10:58  
Dmitry Fedoseev:

Обана, сюрпризик:

 Примерно на каждом 15-20 запуске скрипта выскакивает хвост.

Странно, что именно Вас это удивляет.

Используйте

DoubleToString()

что бы скрыть хвосты от глаз. на самом деле хвосты останутся в любом случае.

А

NormalizeDouble()

будет не к месту, если понадобится использовать шаг, отличный от степени 10.

Dmitry Fedoseev
42924
Dmitry Fedoseev 2015.07.19 11:08  
Andrey Dik:

1. Странно, что именно Вас это удивляет.

2. Используйте

что бы скрыть хвосты от глаз. на самом деле хвосты останутся в любом случае.

А

3. будет не к месту, если понадобится использовать шаг, отличный от степени 10.

Неужели и здесь будут доказывать, что это фича? 

1. Почему это не должно удивлять? Нормализация должна убирать хвосты, для того она и существует. 

2. Вот только, что с глаз скрыть.  Какой в этом смысл? Число реально должно быть без хвостов. 

3. К месту. Шаг имеет заданное количество знаков после запятой.

***

Вот еще интересное наблюдение: 

 

Вот такой вывод: Alert(r," ",DoubleToStr(r,16));  

Andrey Dik
11353
Andrey Dik 2015.07.19 11:39  
Dmitry Fedoseev:

Неужели и здесь будут доказывать, что это фича?

Мой код выше смотрели? Все Ваши "проблемы" уже давно решены. :)
Dmitry Fedoseev
42924
Dmitry Fedoseev 2015.07.19 12:06  
Andrey Dik:
Мой код выше смотрели? Все Ваши "проблемы" уже давно решены. :)

Дауж.. видел. 

Эти тридцать три этажа кода решаются тремя строками.  Просто убираем из моего кода нормализацию и все.

123
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий