我发现,当你给它2的幂时,这个方法似乎失败了。给定两个不同种子的随机对象,当被要求返回介于0(包含)和2的幂之间的整数时,它们返回的第一个整数似乎是相同的;种子并不重要。例如:
public static void main(String[] args) {
Random mRandom;
for (int i = 0; i < 10; i++) {
mRandom = new Random(i);
System.out.println(mRandom.nextInt((int) Math.pow(2, 4)));
}
}
Console:
11
11
11
11
11
11
11
11
11
11我任意选择了2^4,但它似乎适用于任何2的幂。到底怎么回事?此外,我怎样才能避免这种情况?
发布于 2013-11-18 06:27:55
这个问题是由两个原因造成的。
Random类相同的种子。nextInt(int n),如果n是2的幂1.随机类的相同种子。
因为,您已经使用新的Random值启动了新的seed实例,该值对nextInt值生成有影响。根据随机(长种子)的Java文档。
使用单个长种子创建新的随机数生成器。种子是由方法next(int)维护的伪随机数生成器内部状态的初始值。 调用新随机(种子)等价于:随机rnd =新随机();rnd.setSeed(种子);
如果您尝试生成随机值,如果不使用new seed,它将生成真正的随机值,即使是Random类的新实例。
for (int i = 0; i < 10; i++) {
mRandom = new Random(); // Without seed
System.out.println(mRandom.nextInt((int) Math.pow(2, 4)));
}输出:2 1 12 4 3 9 8 2 9
2.在nextInt(int n)上,如果n是2的幂
此外,Random#nextInt具有2的幂效应,如果n是2的幂,它将返回对同一个n总是相同的(int)((n * (long)next(31)) >> 31)。根据nextInt算法,
public int nextInt(int n) {
if (n <= 0)
throw new IllegalArgumentException("n must be positive");
if ((n & -n) == n) // i.e., n is a power of 2
return (int)((n * (long)next(31)) >> 31);
int bits, val;
do {
bits = next(31);
val = bits % n;
} while (bits - val + (n-1) < 0);
return val;
}发布于 2013-11-18 06:37:25
如果您愿意的话,您还可以使用Math.random和Math.pow来进行更简单的操作。
for (int i = 0; i < 10; i++) {
int pows = (int) Math.pow(2, 4);
int random = (int)(Math.random()*pows);
System.out.println(""+random);
} https://stackoverflow.com/questions/20041387
复制相似问题