从Java文档中获得
nextInt():
所有2 32个 可能的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作为32
次位,保证一个非负的值)。但是(正如jjb的注释中指出的那样),由于
next(int)是的
protected方法
Random,因此您必须子类化
Random以公开该方法(或为该方法提供合适的代理):
public class MyRandom extends Random { public MyRandom() {} public MyRandom(int seed) { super(seed); } public int nextNonNegative() { return next(Integer.SIZE - 1); }}另一种方法是使用
ByteBuffer包装4字节数组的a。然后,您可以生成一个随机的四个字节(通过调用
nextBytes(byte[])),将符号位清零,然后将值读取为
int。我不认为这比上面提供了任何优势,但我认为我只是将它扔在那里。基本上与我的第一个解决方案相同(用掩盖
Integer.MAX_VALUE)。
在此答案的早期版本中,我建议使用:
int s = rng.nextInt(Integer.MAX_VALUE);
但是,根据文档,这将生成范围为0(含)至
Integer.MAX_VALUE(不含)的整数。换句话说,它不会产生value
Integer.MAX_VALUE。此外,事实证明,
next(int)它总是比快
nextInt(int)。



