为什么java.util.Random使用掩码?

maa*_*nus 5 java random masking

简化(即,退出并发)Random.next(int bits)看起来像

protected int next(int bits) {
    seed = (seed * multiplier + addend) & mask;
    return (int) (seed >>> (48 - bits));
}
Run Code Online (Sandbox Code Playgroud)

掩码用于将种子减少到48位.为什么它比仅仅更好

protected int next(int bits) {
    seed = seed * multiplier + addend;
    return (int) (seed >>> (64 - bits));
}
Run Code Online (Sandbox Code Playgroud)

?我已经阅读了很多关于随机数的内容,但是没有理由这样做.

hel*_*922 5

原因是较低的位往往具有较低的周期(至少在Java使用的算法中)

来自维基百科 - 线性同余生成器:

如上所示,LCG并不总是使用它们产生的值中的所有位.Java实现在每次迭代时产生48位,但仅从这些值返回32个最高有效位.这是因为高阶位具有比低阶位更长的周期(见下文).使用这种技术的LCG比不使用这种技术的产生更好的价值.

编辑:

在进一步阅读之后(方便地,在维基百科上),a,c和m的值必须满足这些条件才能拥有整个期间:

  1. c和m必须是相对素数

  2. a-1可被m的所有素因子整除

  3. 如果m是4的倍数,则a-1是4的倍数

我能说清楚的唯一一个仍然是#3.需要检查#1和#2,我感觉这些中的一个(或两个)都失败了.


maa*_*nus 0

这样做似乎没有充分的理由。使用掩模是一种保守的方法,使用经过验证的设计。忽略它很可能会带来更好的生成器,但是,在不了解数学的情况下,这是一个冒险的步骤。

掩码的另一个小优点是 8 位架构上的速度增益,因为它使用 6 个字节而不是 8 个字节。