What is wrong with this broken Java Random.nextInt (long) behavior?

I found that this method seems to fail when you feed it with force 2. Given two random objects from different seeds, it seems that the first integer that they return when asked to return an integer from 0 (inclusive), and the power of two (exclusive) is always the same; seeds do not matter. For example:

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 

I chose 2 ^ 4 arbitrarily, but it seems to work for any power of two. What's happening? Also, how can I avoid this?

+8
java random
source share
2 answers

This problem occurs for two reasons.

  • Same seed for class Random .
  • In nextInt(int n) , if n is a power of 2

1. The same seed for the Random class.

Since you initiated a new instance of Random with a new seed value, which affects the generation of the nextInt value. According to Java Random docs (long seed) .

Creates a new random number generator using one long seed. The initial value is the initial value of the internal state of the pseudo random number generator, which is supported by the next (int) method.

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

If you try to create a random value, without a new seed , than it will generate a real random value, even if a new instance of the Random class.

 for (int i = 0; i < 10; i++) { mRandom = new Random(); // Without seed System.out.println(mRandom.nextInt((int) Math.pow(2, 4))); } 

Output: 2 1 12 4 3 9 9 8 2 9

2. In nextInt (int n), if n is a power of 2

In addition, Random # nextInt affects power 2. If n is 2, it will return (int)((n * (long)next(31)) >> 31) , which will always be the same for the same n. According to the nextInt algorithm,

 public int nextInt(int n) { if (n <= 0) throw new IllegalArgumentException("n must be positive"); if ((n & -n) == n) // ie, 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; } 
+5
source share

You can also use Math.random and Math.pow for greater simplicity if you wish.

 for (int i = 0; i < 10; i++) { int pows = (int) Math.pow(2, 4); int random = (int)(Math.random()*pows); System.out.println(""+random); } 
0
source share

All Articles