xorshift 伪随机数生成器
xorshift 伪随机数生成器详解
一、什么是 xorshift
xorshift 是一种伪随机数生成器(PRNG),由 George Marsaglia 在 2003 年提出。它的核心思想是:
只用异或(XOR)和移位(shift)两种位运算,就能生成质量不错的伪随机序列。
名字就来自 XOR + Shift = xorshift。
它的最大优点是:
- 极快:只有异或和移位,没有乘除、取模。
- 代码短:几行就能实现。
- 周期长:合理选择参数可达到 2³²−1 或 2⁶⁴−1。
- 无需大表:不像梅森旋转需要大量状态。
因此在竞赛、游戏、嵌入式、甚至一些语言的标准库里都有应用。
二、基本形式
2.1 最简单的 32 位 xorshift
uint32_t x = 123456789; // 种子,不能为 0
uint32_t xorshift32() {
x ^= x << 13;
x ^= x >> 17;
x ^= x << 5;
return x;
}
这三行就是经典的 xorshift32,参数 (13, 17, 5) 是 Marsaglia 推荐的。
2.2 执行过程
每一步都是:
x ^= x << 13;:把 x 左移 13 位后与原 x 异或。x ^= x >> 17;:把 x 右移 17 位后异或。x ^= x << 5;:把 x 左移 5 位后异或。
最后返回 x,同时 x 作为下一次的种子(状态)。
2.3 为什么不能种子为 0?
如果 x = 0:
0 << 13 = 00 ^ 0 = 0- 后面全是 0,永远出不来。
所以 种子必须非 0。
三、手动模拟一个小例子
为了看清 xorshift 怎么工作,我们用 8 位 简化版(实际不推荐,周期太短),参数用 (3, 2, 1):
初始 x = 10011001(二进制)
第一步:x ^= x << 3
x = 10011001
x << 3 = 11001000 (左移3位,低位补0,高位溢出丢弃)
异或:
10011001
^ 11001000
= 01010001
现在 x = 01010001
第二步:x ^= x >> 2
x = 01010001
x >> 2 = 00010100
异或:
01010001
^ 00010100
= 01000101
现在 x = 01000101
第三步:x ^= x << 1
x = 01000101
x << 1 = 10001010
异或:
01000101
^ 10001010
= 11001111
最终 x = 11001111,作为随机数输出,同时成为下一次的状态。
四、为什么 xorshift 能生成随机数?
关键在于异或和移位是可逆的线性变换(在 GF(2) 上)。
- 每一次
x ^= x << k或x ^= x >> k都是一个可逆的线性变换。 - 整个 xorshift 就是几个可逆变换的复合,因此也是一个可逆变换。
- 在 32 位空间中,非零状态共有 2³²−1 个。如果参数选得好,这个变换会遍历所有非零状态,形成一个长度为 2³²−1 的循环。
- 这就是它的周期。
所以 xorshift 本质上是在一个巨大的状态空间里做确定性的跳跃,看起来像随机。
五、常见变体
5.1 xorshift64
uint64_t x = 88172645463325252ULL;
uint64_t xorshift64() {
x ^= x << 13;
x ^= x >> 7;
x ^= x << 17;
return x;
}
周期 2⁶⁴−1。
5.2 xorshift128
用 4 个 32 位状态,周期可达 2¹²⁸−1,质量更好。
uint32_t x, y, z, w;
uint32_t xorshift128() {
uint32_t t = x ^ (x << 11);
x = y; y = z; z = w;
w = w ^ (w >> 19) ^ (t ^ (t >> 8));
return w;
}
5.3 xorshift128+
在 xorshift128 基础上加一步加法,改善统计质量,被很多语言采用(如 V8 引擎的 Math.random 早期版本)。
uint64_t s[2];
uint64_t xorshift128plus() {
uint64_t x = s[0];
uint64_t const y = s[1];
s[0] = y;
x ^= x << 23;
s[1] = x ^ y ^ (x >> 17) ^ (y >> 26);
return s[1] + y;
}
5.4 xoshiro / xoroshiro
xorshift 的后继者,质量更高,周期更长,被现代语言广泛使用。

浙公网安备 33010602011771号