除了使用Lehmer MCG之外,您还可以使用以下几种:
Xorshift的32 位变体使用 32 位状态保证周期为 2 32 -1 :
uint32_t state;
uint32_t xorshift32(void) {
state ^= state << 13;
state ^= state >> 17;
state ^= state << 5;
return state;
}
这是 2003 年最初的 32 位建议(见论文)。根据您对“体面的质量”的定义,那应该没问题。然而,它没有通过Diehard的二进制等级测试和 SmallCrush 的 5/10 测试。
具有更好混合和常数的替代版本(通过 SmallCrush 和 Crush):
uint32_t xorshift32amx(void) {
int s = __builtin_bswap32(state * 1597334677);
state ^= state << 13;
state ^= state >> 17;
state ^= state << 5;
return state + s;
}
基于这里和这里的研究。
还有Mulberry32,它的周期正好是2 32:
uint32_t mulberry32(void) {
uint32_t z = state += 0x6D2B79F5;
z = (z ^ z >> 15) * (1 | z);
z ^= z + (z ^ z >> 7) * (61 | z);
return z ^ z >> 14;
}
这可能是您最好的选择。这是相当不错。作者指出“它通过了 gjrand 的 13 次测试,没有失败,并且在 4GB 生成的数据上,总 P 值为 0.984(其中 1 是完美的,0.1 或更少是失败)。这是整个周期的四分之一”。它似乎是对 SplitMix32 的改进。
“SplitMix32”,采用 xxHash/MurmurHash3(Weyl 序列):
uint32_t splitmix32(void) {
uint32_t z = state += 0x9e3779b9;
z ^= z >> 15; // 16 for murmur3
z *= 0x85ebca6b;
z ^= z >> 13;
z *= 0xc2b2ae35;
return z ^= z >> 16;
}
这里的质量可能有问题,但它的 64 位大哥有很多粉丝(通过 BigCrush)。所以总体结构值得一看。