这个破坏的Java Random.nextInt(长)行为怎么了?

时间:2013-11-18 06:23:29

标签: java random

我发现这种方法在你给它2的幂时似乎很难失败。鉴于两个不同种子的随机对象,它们似乎是当被要求返回0之间的整数时返回的第一个整数(包括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的力量。这是怎么回事?此外,我该如何避免这种情况?

2 个答案:

答案 0 :(得分:5)

出现此问题的原因有两个。

  1. Random类的相同种子。
  2. nextInt(int n),如果n是2的幂
  3. 1。随机类的相同种子。

    因为您启动了新的Random实例,其新seed值会对nextInt值生成产生影响。根据{{​​3}}的Java文档。

      

    使用单个长种子创建新的随机数生成器。种子是初始值   的内部状态   伪随机数生成器,由方法next(int)维护。

    The invocation new Random(seed) is equivalent to:
    
     Random rnd = new Random();
     rnd.setSeed(seed);
    

    如果您尝试生成随机值,而不是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 9 8 2 9

    2.在nextInt(int n),如果n是2的幂

    除此之外,Random(long seed)具有2的幂的效果。如果n是2的幂,则它将返回(int)((n * (long)next(31)) >> 31),对于相同的n,它将始终相同。根据{{​​1}}算法,

    nextInt

答案 1 :(得分:0)

如果需要,您还可以将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);
}