との問題はsrand
、rand
それらの呼び出しシグネチャのみ(およびそれらが生成する値ではない)がC標準によって指示されることです。移植可能で決定論的な疑似乱数が必要な場合は、自分で実装する必要があります。これはC++で書かれたクラスで、Numerical Recipesにあるクラスに基づいており、完全に移植可能です。必要に応じて、シードを使用して乱数ストリームをインスタンス化できます。同じ疑似ランダムシーケンスが何度も必要になる場合に備えて、時間を使用する代わりにこのシードをハードコーディングします。このメソッドを使用して、RandomInteger(a,b)
半開区間[a、b)の整数を取得することもできます。
class RandomNumberStream
{
private:
unsigned long long u,v,w;
public:
RandomNumberStream(int n=1);
double RandomDouble();
double RandomDouble(double a, double b);
unsigned long long RandomInteger();
unsigned long long RandomInteger(int a, int b);
private:
unsigned long long int64();
} ;
RandomNumberStream::RandomNumberStream(int n)
{
v = 4101842887655102017LL;
w = 1;
u = n^v; int64();
v = u; int64();
w = v; int64();
}
double RandomNumberStream::RandomDouble()
{
return int64() * 5.42101086242752217E-20f;
}
double RandomNumberStream::RandomDouble(double a, double b)
{
return int64() * 5.42101086242752217E-20f * (b-a) + a;
}
unsigned long long RandomNumberStream::RandomInteger()
{
return int64();
}
unsigned long long RandomNumberStream::RandomInteger(int a, int b)
{
return a + int64() % (b-a);
}
unsigned long long RandomNumberStream::int64()
{
u = u * 2862933555777941757LL + 7046029254386353087LL;
v ^= v>>17; v ^= v<<31; v ^= v>>8;
w = 4294957665U*(w & 0xffffffff) + (w>>32);
unsigned long long x = u^(u<<21); x ^= x>>35; x ^= x<<4;
return (x+v)^w;
}