我试图理解 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 ...
答案 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位整数算术,那本可以写它。