在Java中使用线性同余方程的实现

时间:2014-02-20 11:37:20

标签: java math random

我在Random class中看到了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

但上面的代码看起来并不相似。相反,它使用&amp;代替模数操作,如下线

nextseed =(oldseed * multiplier + addend)&amp;掩模;

有人可以帮我理解这种使用&amp; amp;和而不是模运算?

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

如果mask + 1是2的幂,则可以使用此方法。

例如,如果你想做模4,你可以写x & 3而不是x % 4来获得相同的结果。

但请注意,这需要x号。