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 ms 根据rnu.Rand_01()文章缩短 - 596 ms 我的优化版RandomInteger() - 840毫秒(旧版1200毫秒,即快25%)。 仅仅通过MathRand() - 353 ms(最快,但分布会不均匀。如果要求的数字范围大于32767,结果将被跳过。如果小于32767,例如i=31111.那么四舍五入会更频繁地出现在某些点上)。
Потребовалась функция ГСЧ с гнерацией числа Int от 0 до любого значения.Получилась такая функция. Думаю распределение получилось равномерным. int RandomInteger(int max_vl){return
请告诉我MathRand()如何取值。
我们能指望MathRand()在声明的范围内均匀分布吗?
这里是一个例子,当然还有其他更复杂的算法...
source rand.c :
需要一个RNG函数,数字Int从0到任意值。
由于Int的最大值=2,147,483,647,所以我们计算到它。
我们已经得到了这个函数。我认为分布是均匀的。
该文章 有一个发电机高达4294967295
Alglib SB有一个高精度的振荡器
UPD: 我试了一下https://www.mql5.com/ru/forum/324066#comment_13500222 , 似乎可以工作,但MQL5中没有Alglib的文档,你应该在Alglib网站上阅读。
该文章 有一个发电机到4294967295
谢谢,我从计算速度方面进行了比较。
![](https://c.mql5.com/3/316/Untitled-1.png)
我在标准rand()上的函数结果是慢了2倍。虽然代码看起来简单多了...
Alglib SB有一个高精度的振荡器
UPD: 我试了一下https://www.mql5.com/ru/forum/324066#comment_13500222 , 似乎可以工作,但MQL5中没有Alglib的文档,你应该在Alglib网站上阅读。
我看到了,但我希望它不含alglib。此外,该函数有很多*/%。我没有比较它的速度,因为它显然更慢。 文章中的生成器可以用位移来工作--它更快。
重写了我的函数以优化速度。
结果发现分布是均匀的。请看博客中的实验图片https://www.mql5.com/ru/blogs/post/735953我重新写了文章中的RMS。
我丢弃了不必要的东西,这就是我得到的东西。
分配结果也是平等的。
我比较了两个函数的速度,文章中的原始函数和简单的MathRand()。
根据rnu.Rand_01()文章缩短 - 596 ms
我的优化版RandomInteger() - 840毫秒(旧版1200毫秒,即快25%)。
仅仅通过MathRand() - 353 ms(最快,但分布会不均匀。如果要求的数字范围大于32767,结果将被跳过。如果小于32767,例如i=31111.那么四舍五入会更频繁地出现在某些点上)。
利用优势)
为什么要把事情搞得这么复杂?
你可以这样做(大致上说)。
如果你想玩一玩,或者看看它显示了什么,你可以这样做。
并看看它是如何改变数值的。
我已经重写了我的函数以优化速度。
分布是均匀的。请看博客上的实验图片https://www.mql5.com/ru/blogs/post/735953我重写了文章中的RNG。
我丢弃了不必要的东西,这就是我得到的东西。
分布结果也是均匀的。
我把它与帮助中的分布进行了比较,我没有看到任何区别。