我在Random类下看到Java中的LCG实现,如下所示:

/*
 * This is a linear congruential pseudorandom number generator, as
 * defined by D. H. Lehmer and described by Donald E. Knuth in
 * <i>The Art of Computer Programming,</i> Volume 3:
 * <i>Seminumerical Algorithms</i>, section 3.2.1.
 *
 * @param  bits random bits
 * @return the next pseudorandom value from this random number
 *         generator's sequence
 * @since  1.1
 */

protected int next(int bits) {
    long oldseed, nextseed;
    AtomicLong seed = this.seed;
    do {
        oldseed = seed.get();
        nextseed = (oldseed * multiplier + addend) & mask;
    } while (!seed.compareAndSet(oldseed, nextseed));
    return (int)(nextseed >>> (48 - bits));
}


但是下面的链接告诉我们LCG的形式应为x2 =(ax1 + b)modM

https://math.stackexchange.com/questions/89185/what-does-linear-congruential-mean

但是上面的代码看起来并不相似。相反,它使用&代替下面一行中的模运算

nextseed =(oldseed *乘数+加数)&mask;

有人可以帮助我了解使用&而不是取模运算的这种方法吗?

最佳答案

使用形式为2^n - 1的掩码进行按位与运算与计算模2^n的数字相同:数字中最高的任何1都是2^n的倍数,因此可以安全地丢弃。但是请注意,如果将模数设为2的幂(而不是2的幂减去1),则某些乘数/加数组合的工作效果非常差。该代码很好,但是请确保它适合您的常量。

09-25 19:12