从Java docs for nextInt()
:
所有2 可能INT值的生成(大致)相同的概率。
一种方法是使用下面的变换:
s = rng.nextInt() & Integer.MAX_VALUE; // zero out the sign bit
这样的事情需要(而不是使用绝对值或否定)的原因是,Integer.MIN_VALUE
的绝对值太大,无法在变成了一个正整数。也就是说,由于溢出,Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE
和Integer.MIN_VALUE == -Integer.MIN_VALUE
。上面的转换保留了大致均匀的分布属性:如果您编写了一个产生和测试循环,它只丢掉了Integer.MIN_VALUE
并返回了其他所有值的绝对值,那么正整数将为零的两倍。通过将Integer.MIN_VALUE
映射到零,这使得零的概率与正整数一致。
下面是另一种方法,这实际上可以是一点点更快(虽然我没有基准它):
int s = rng.next(Integer.SIZE - 1); // Integer.SIZE == 32
这将产生具有31随机低阶位(和0作为整数保证非负值)。但是(如在由JJB的评论中指出),因为next(int)
是Random
一个protected
方法,你就必须继承Random
揭露方法(或提供方法的合适的代理):
public class MyRandom extends Random {
public MyRandom() {}
public MyRandom(int seed) { super(seed); }
public int nextNonNegative() {
return next(Integer.SIZE - 1);
}
}
另一种方法是使用包装4字节数组的ByteBuffer
。然后,您可以生成一个随机的四个字节(通过调用nextBytes(byte[])
),将符号位置零,然后将该值作为int
读取。我不认为这提供了比上述任何优势,但我认为我只是把它扔在那里。它基本上与我的第一个解决方案相同(用Integer.MAX_VALUE
掩盖)。
在这种应答的早期版本,我建议使用:
int s = rng.nextInt(Integer.MAX_VALUE);
然而,根据the docs这将产生范围为0(含)的整数Integer.MAX_VALUE
(独家)。换句话说,它不会生成值Integer.MAX_VALUE
。另外,事实证明next(int)
总是会比nextInt(int)
更快。
只相信你在javadocs中阅读的内容。和(当然)**阅读javadocs **。 – 2011-04-29 04:07:36
注意'Math.abs'不会在2中工作一次。 (提示:不要使用静态可变对象) – 2011-04-29 09:53:55