【发布时间】:2021-06-06 21:05:07
【问题描述】:
我正在研究 Java Random 库在给定上限的情况下生成整数的方式,但我不太了解该算法。在文档中它说:
算法有点棘手。它拒绝可能导致的值 分布不均匀(由于 2^31 不可整除 由 n)。一个值被拒绝的概率取决于 n。这 最坏的情况是 n=2^30+1,拒绝的概率是 1/2, 循环终止前的预期迭代次数为 2。
但我真的不明白这个实现是如何考虑到这一点的,特别是代码中的while 条件。对我来说,这似乎(几乎)总是会以 50% 的成功率成功。尤其是在查看 bound 的非常低的值时(我认为在施加界限时经常使用它)。在我看来,while 中的条件只是检查bits 的符号,那么为什么还要打扰他们使用的线路呢?
public int nextInt(int bound) {
if (bound <= 0)
throw new IllegalArgumentException("bound must be positive");
if ((bound & -bound) == bound) // i.e., bound is a power of 2
return (int)((bound * (long)next(31)) >> 31);
int bits, val;
do {
bits = next(31);
val = bits % bound;
} while (bits - val + (bound-1) < 0);
return val;
}
【问题讨论】:
-
有趣的是
ThreadLocalRandom::nextInt的实现方式不同