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 ms (旧バージョン 1200 ms, すなわち 25% 高速化) MathRand()だけで-353ms(最速ですが、分布にばらつきが出ます。必要な数値の範囲が32767より大きい場合、結果はスキップされます。32767より小さい場合、例えばi=3111.のような場合、丸めの頻度が高くなる点がある)。
Потребовалась функция ГСЧ с гнерацией числа Int от 0 до любого значения.Получилась такая функция. Думаю распределение получилось равномерным. int RandomInteger(int max_vl){return
MathRand()が値を取得する方法を教えてください。
MathRand()は、宣言した範囲内で均等になることを期待できますか?
もちろん、もっと複雑なアルゴリズムもあります。
ソース rand.c :
0から任意の値までの数値IntでRNG機能が必要です。
Intの最大値=2,147,483,647なので、その値まで計算 する。
この関数を取得しました。分布は一様 だと思います。
記事には、4294967295までの ジェネレーターがあります。
Alglib SBは高精度な発振器を搭載しています
UPD: https://www.mql5.com/ru/forum/324066#comment_13500222 試してみました。
記事には、4294967295への ジェネレーターがあります。
ありがとうございます。計算速度で比較してみました。
標準的なrand()の私の関数では、2倍も遅いことが判明しました。もっとシンプルなコードに見えたのに...。
Alglibの高精度ジェネレータがある
UPD: https://www.mql5.com/ru/forum/324066#comment_13500222 試してみました。
見たけど、alglib抜きで欲しい。さらに、その関数には多くの*/%があります。明らかに遅いので、速度の比較はしていません。 記事中のジェネレータはビットシフトで動作します。その方が高速です。
速度を最適化するために関数を書き直しました。
その結果、分布は一様であることが判明しました。実験の画像はブログでご覧くださいhttps://www.mql5.com/ru/blogs/post/735953記事からRMSを書き直しました。
不要なものを捨てたら、こうなった。
分配も平等であることがわかりました。
記事のオリジナルと単純なMathRand()の両方の関数の速度を比較してみました。
rnu.Rand_01()の記事による短縮版 - 596 ms
RandomInteger()の最適化バージョン - 840 ms (旧バージョン 1200 ms, すなわち 25% 高速化)
MathRand()だけで-353ms(最速ですが、分布にばらつきが出ます。必要な数値の範囲が32767より大きい場合、結果はスキップされます。32767より小さい場合、例えばi=3111.のような場合、丸めの頻度が高くなる点がある)。
活用する)
なぜ、そこまで複雑にするのか?
このようにできます(大雑把ですが)。
また、遊んでみたい、何を表示しているのか見てみたいという場合は、このようにすることができます。
を実行し、値がどのように変化するかを確認します。
速度を最適化するために、関数を書き直しました。
分布は均一である。実験の画像はブログでご覧くださいhttps://www.mql5.com/ru/blogs/post/735953記事からRNGを書き換えてみました。
不要なものを捨てたら、こうなった。
分布も一様であることがわかります。
ヘルプのディストリビューションと比較してみましたが、特に違いは見当たりません