【问题标题】:Confusing implementation of java.util.Random nextInt(int n)java.util.Random nextInt(int n) 的令人困惑的实现
【发布时间】:2015-03-18 21:29:09
【问题描述】:

我试图了解 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)

鉴于 bits 值为 31 位长,即 bits 始终为正,是否为负?如果 bits 为正,则 val 始终小于 bits 然后 while 条件始终保持 > 0...

【问题讨论】:

  • next(int n) 合约说n 的低位将是近似随机的。它不对高位进行断言。高位可以是01。当它是1 时,bits 的值为负数。

标签: java random


【解决方案1】:

implementation-of-java-util-random-nextint. 已经解决了这个问题

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

我们在数学上检查:

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

如果 java 有无符号 32 位整数运算,也可以按原样写。

【讨论】:

  • 谢谢,这很有帮助。我应该在问之前更加努力!
【解决方案2】:

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

【讨论】:

  • Daniel,我应该在这里复制 nextInt() 的整个实现。它的第一行检查 n 是否为正:if (n &lt;= 0) throw new IllegalArgumentException("n must be positive");
  • 好的,剩下第三个选项 ;-)
  • 谢谢你,丹尼尔!是的,我完全错过了溢出是这里算法的一部分这一事实。
猜你喜欢
  • 1970-01-01
  • 2012-01-02
  • 1970-01-01
  • 2018-02-26
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 2022-01-17
  • 1970-01-01
相关资源
最近更新 更多