令人困惑的java.util.Random nextInt(int n)的实现

时间:2015-03-18 21:29:09

标签: java random

我试图理解 java.util.Random.nextInt(int n)是如何工作的,尽管所有搜索甚至调试都无法完全理解实现。

while 循环导致混淆: http://docs.oracle.com/javase/7/docs/api/java/util/Random.html#nextInt(int)

int bits, val;
do {
    bits = next(31);
    val = bits % n;    
} while (bits - val + (n-1) < 0);

我意识到这应该解决模数偏差,但很难看出如何。

问题:怎么可能表达

bits - val + (n-1)

为负,假设值为31位长,即总是为正?如果为正,则 val 始终小于,然后,而条件始终保持&gt; 0 ...

2 个答案:

答案 0 :(得分:1)

您在计算中缺少n的值。 n为负数,bits - val -1 1 < n或其他N足以使整数溢出并成为负数。

答案 1 :(得分:1)

implementation-of-java-util-random-nextint.

已经解决了这个问题

基本上,我们必须删除bits范围内[0..2^31[的最顶层元素,因为它们会导致非均匀分布

我们在数学上检查:

bits - val + (n-1) >= 2^31

如果java有无符号的32位整数算术,那本可以写它。