在Josh提供的例子中,展示了一种存在缺陷的随机方法,该方法可生成一个给定上限n
的正随机数。我不理解他所谈到的两种缺陷。
书中的方法如下:
private static final Random rnd = new Random();
//Common but deeply flawed
static int random(int n) {
return Math.abs(rnd.nextInt()) % n;
}
- 他说如果 n 是 2 的一个小幂,生成的随机数序列将在短时间内重复。为什么会这样?
Random.nextInt()
的文档说明为“从该随机数生成器的序列中返回下一个伪随机、均匀分布的 int 值”。那么如果 n 是一个小整数,序列不应该重复吗?为什么只适用于 2 的幂次方? - 接下来他说,如果 n 不是 2 的幂,则某些数字将平均更频繁地返回。如果
Random.nextInt()
生成的整数是均匀分布的,为什么会出现这种情况?(他提供了一个代码片段,清楚地证明了这一点,但我不明白为什么会这样,以及这与 n 是 2 的幂次方有什么关系)。
rnd.nextInt(n)
- Elliott FrischMath.abs
的文档说明:“请注意,如果参数等于Integer.MIN_VALUE
,即可表示的最小负整数值,则结果是相同的值,即为负数。” http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#abs(int) (我还确认了rnd.nextInt()
确实可以返回Integer.MIN_VALUE
)。负值对正数n
取模的结果是负值。 - Mooing Duck