Потребовалась функция ГСЧ с гнерацией числа Int от 0 до любого значения.
Так как максимальное значение Int =2 147 483 647, расчет ведем до негою
Получилась такая функция. Думаю распределение получилось равномерным.
int RandomInteger(int max_vl){//случайное Int от 0 до Max Int//srand(0);//если нужна повторяемость. MathSrand(GetTickCount()) если нужна неповторяемостьint r=MathRand();// от 0 до 32767.double k=32767.0;
if(max_vl>32767){
r=r+MathRand()*32767;//0...32767 + 0.. 32767*32767(с шагом 32767) max=1073709056 > 1 mlrd
k=k*k;
if(max_vl>1073709056){// int type max alue =2 147 483 647 > 2 mlrd
r=r*2+MathRand()%2;//0...2 147 483 647 > to max int number c шагом 2 + (0 или 1)
k=k*2;
}
}
return (int)MathFloor(r/k*max_vl);
}
Да я его видел, но хочется без алглиба. К тому же та функция содержит массу */%. Сравнивать по скорости не стал, очевидно она медленнее. Генератор из статьи работает с побитовыми смещениями- это быстро.
Переписал ГСЧ из статьи. Отбросил лишнее, вот что получилось:
//если из define переместить в код RNDUint, то скорость работы увеличится на 30% для 10 млн повторов с 600 мс до 850 мс#define xor32 xx=xx^(xx<<13);xx=xx^(xx>>17);xx=xx^(xx<<5)
#define xor128 t=(x^(x<<11));x=y;y=z;z=w;w=(w^(w>>19))^(t^(t>>8))
#define inidat x=123456789;y=362436069;z=521288629;w=88675123;xx=2463534242class RNDUint{
protected:
uint x,y,z,w,xx,t;
public:
RNDUint(void){inidat;};
~RNDUint(void){};
uint Rand() {xor128;return(w);};//равномерное распределение на отрезке [0,UINT_MAX=4294967295].double Rand_01() {xor128;return((double)w/UINT_MAX);};//равномерное распределение на отрезке [0,1].void Reset() {inidat;};//сброс всех исходных значений в первоначальное состояние.void SRand(uint seed) {//установка новых исходных значений генератора.seed= [0,UINT_MAX=4294967295]. При seed=0 функция меняет начальные значения случайным образом.int i;if(seed!=0){xx=seed;}for(i=0;i<16;i++){xor32;}xor32;x=xx;xor32;y=xx;xor32;z=xx;xor32;w=xx;for(i=0;i<16;i++){xor128;}
};
};
Распределение тожеполучилось равномерным.
Сделал сравнение по скорости обоих функций, оригинальной из статьи и просто MathRand():
Оригинальная из статьи Rnd.Rand_01() - 602 мс Укороченная по статье rnu.Rand_01() - 596 мс Моя оптимизированная версия RandomInteger() - 840 мс (старая версия 1200 мс, т.е. ускорил на 25%) Просто по MathRand() - 353 мс (самая быстрая, но распределение будет неравномерным. Если диапазон требуемых чисел больше 32767, то результат будет с пропусками. Если меньше 32767, например i=31111. то к части точек округление будет происходить чаще.)
Потребовалась функция ГСЧ с гнерацией числа Int от 0 до любого значения.Получилась такая функция. Думаю распределение получилось равномерным. int RandomInteger(int max_vl){return
Расскажите, плз, как MathRand() получает значения.
Можно ли ожидать равномерное распределение MathRand() в заявленном диапазоне?
вот один из примеров, конечно существуют и другие, более сложные алгоритмы...
исходник rand.c :
Потребовалась функция ГСЧ с гнерацией числа Int от 0 до любого значения.
Так как максимальное значение Int =2 147 483 647, расчет ведем до негою
Получилась такая функция. Думаю распределение получилось равномерным.
В статье есть генератор до 4294967295
в СБ Алглиб есть генератор повышенной точности
UPD: вот пробовал разобраться с ним https://www.mql5.com/ru/forum/324066#comment_13500222 , вроде работает, но документации по Алглиб в MQL5 нет, на сайте алглиб нужно почитать
В статье есть генератор до 4294967295
Спасибо, сравнил по скорости вычислений.

Моя функция на стандартном rand() оказалась в 2 раза медленнее. Хотя казалось бы код намного проще...
в СБ Алглиб есть генератор повышенной точности
UPD: вот пробовал разобраться с ним https://www.mql5.com/ru/forum/324066#comment_13500222 , вроде работает, но документации по Алглиб в MQL5 нет, на сайте алглиб нужно почитать
Да я его видел, но хочется без алглиба. К тому же та функция содержит массу */%. Сравнивать по скорости не стал, очевидно она медленнее. Генератор из статьи работает с побитовыми смещениями- это быстро.
Переписал свою ф-ю для оптимизации скорости:
Распределение получилось равномерным. См. изображения эксперимента в блоге https://www.mql5.com/ru/blogs/post/735953Переписал ГСЧ из статьи.
Отбросил лишнее, вот что получилось:
Распределение тожеполучилось равномерным.
Сделал сравнение по скорости обоих функций, оригинальной из статьи и просто MathRand():

Оригинальная из статьи Rnd.Rand_01() - 602 мсУкороченная по статье rnu.Rand_01() - 596 мс
Моя оптимизированная версия RandomInteger() - 840 мс (старая версия 1200 мс, т.е. ускорил на 25%)
Просто по MathRand() - 353 мс (самая быстрая, но распределение будет неравномерным. Если диапазон требуемых чисел больше 32767, то результат будет с пропусками. Если меньше 32767, например i=31111. то к части точек округление будет происходить чаще.)
Пользуйтесь)
зачем так всё усложнять?
можно же так (грубо говоря):
А если поиграться хочется или посмотреть что как показывает, то так:
и смотрим как он меняет значения.
Переписал свою ф-ю для оптимизации скорости:
Распределение получилось равномерным. См. изображения эксперимента в блоге https://www.mql5.com/ru/blogs/post/735953Переписал ГСЧ из статьи.
Отбросил лишнее, вот что получилось:
Распределение тожеполучилось равномерным.
Сравнил с распределением из справки, разницы не вижу