但是,即使您不想使用 C++ 11 标准,Knuth 也会为您提供帮助 - 这是我很久以前(当库只提供rand())根据 Knuth 编写的几个生成器(对不起,我不会重写算法,请参阅书籍):
class Random
{
public:
typedef int RandomValue;
Random& operator = (int seed) { X = seed; return *this; }
Random(int seed = 1):X(seed){};
int operator()(int seed = 0)
{
const int MM = 2147483647;
const int AA = 48271;
const int QQ = 44488;
const int RR = 3399;
if (seed != 0) X = seed;
X = AA*(X%QQ)-RR*(X/QQ);
if (X < 0) X += MM;
return X-1;
}
// Не включая max
int operator()(int min, int max)
{
return (*this)()%(max-min) + min;
}
private:
int X;
};
class Random64
{
typedef unsigned long long uint64;
public:
typedef uint64 RandomValue;
Random64& operator = (uint64 seed) { X = seed; return *this; }
Random64(uint64 seed = 0):X(seed){};
uint64 operator()(uint64 seed = uint64(-1))
{
const uint64 a = 3202034522624059733ULL;
const uint64 c = 1ULL;
if (seed != uint64(-1)) X = seed;
uint64 Y = a * X + c;
X = a * Y + c;
Y = (Y&0xFFFFFFFF00000000ULL) | (X >> 32);
return Y;
}
// Не включая max
uint64 operator()(uint64 min, uint64 max)
{
return (*this)()%(max-min) + min;
}
private:
uint64 X;
};
仅有的?
十亿很合适
int。它将long long容纳数十亿 - 对于标准库来说,这是一个正常的全职工作......标准库
<random>可以提供帮助。但是,即使您不想使用 C++ 11 标准,Knuth 也会为您提供帮助 - 这是我很久以前(当库只提供
rand())根据 Knuth 编写的几个生成器(对不起,我不会重写算法,请参阅书籍):这是一个工作示例。
如果您有一个现成的具有
n位长度的数字生成器,那么您可以通过从对现有生成器的连续调用中获得的位序列的通常串联来从中获得更长数字的生成器。在您的问题中,您提到了一个生成 15 个伪随机位的生成器。对此类生成器的五次调用将为您提供一个 64 位伪随机数
“额外”位,如果有的话,你可以简单地扔掉(就像我上面做的那样),或者你可以保存下一个长数字。
当然,没有免费的早餐。由于生成器内部状态的大小保持不变,并且生成的数字变长了,所以在其他地方有些东西变得“更短”了。即:这种发电机的周期变短了相应的次数。这是否重要取决于您的应用程序。
这是 unsigned long long 的生成示例
您还可以查看Stephen Wolfram 的元胞自动机,它允许您获得任意大的适当的零和一随机序列,并在 Wolfram Mathematica 中用于生成随机数。
它并不复杂,您可以尝试实现它。
如果你有 Linux 正常读取 /dev/urandom 这样的 PRSP
如果赢使用 mt
这是使用 PRNG 生成数据的 4 个函数重载示例