来自 nextInt()
的 Java 文档:
所有 232 个可能的整数值都是以(大约)相等的概率生成的。
一种方法是使用以下转换:
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);
}
}
另一种方法是使用 包装 4 字节数组的 。然后,您可以生成一个随机的四个字节(通过调用),将符号位清零,然后将该值读取为 .我不相信这比上述有任何优势,但我想我会把它扔在那里。它基本上与我的第一个解决方案相同(用 屏蔽)。ByteBuffer
nextBytes(byte[])
int
Integer.MAX_VALUE
在这个答案的早期版本中,我建议使用:
int s = rng.nextInt(Integer.MAX_VALUE);
但是,根据文档,这将生成范围为 0(含)到(不含)的整数。换句话说,它不会产生价值 。此外,事实证明,这总是比 .Integer.MAX_VALUE
Integer.MAX_VALUE
next(int)
nextInt(int)