Random.nextBoolean () always returns true, does not affect seeds

When I run the following code, no matter what range I use for the for loop, the code always prints true ten times.

 public static void main(String[] args) { Random bool = new Random(); for (int i = 0; i < 10; i++) { bool.setSeed(i); System.out.println(bool.nextBoolean()); } } 

However, if I change the code a bit and let the random generator run the nextBoolean() function once before printing, I get a normal distribution of true and false in the output, which changes when the range of the for loop changes:

 public static void main(String[] args) { Random bool = new Random(); for (int i = 0; i < 10; i++) { bool.setSeed(i); bool.nextBoolean(); //Only change System.out.println(bool.nextBoolean()); } } 

It seems to me that the nextBoolean() function always returns true when it is executed for the first time, is there a reason for this behavior?

+6
source share
3 answers

The reason is found in the API for the setSeed method:

The random setSeed implementation uses only 48 bits of a given seed.

In fact, the long that you specify as the initial value is multiplied by a fixed value (defined privately in the Random class), and then only the least significant 48 bits are taken into account. Although this factor is large, because your sequence of i values โ€‹โ€‹is sequential, they all produce initial values โ€‹โ€‹that are numerically similar. Thus, the first few thousand values โ€‹โ€‹are effectively perceived as having the same value for the nextBoolean method, and you get the same initial Boolean value. Calling nextBoolean again (without calling setSeed again) will reassign the initial value, so you quickly move away from viewing the same pattern.

If you call the setSeed method, you only need to call it once, and you must do this outside the loop. But the Random class is fully capable of choosing its own seed value, so I recommend that you donโ€™t call setSeed at all if you donโ€™t know why you are doing this.

+6
source

So basically the nextBoolean method can only return true or false . And the total number of seed values โ€‹โ€‹can be [Long.MIN_VALUE, Long.MAX_VALUE] . So, you can assume that for half of these seeds you get true , and for the other half you get false .

Now that you are repeating 10 numbers, it is possible that for these 10 seeds, the value you get is true . When you try to use a larger range, you are more likely to get an equal distribution of both values.

Now every time you call nextBoolean() , the seed is updated to some other value using (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1) . Therefore, if the current seed is 1 , the next seed will be 25214903916 , where you can get true or false (which you do not know). This is why you sometimes get false when you call nextBoolean() twice in a loop. After all, it is a pseudo random number generator.

By the way, you really don't need to call the setSeed() method. This method is only used to reset for seed for a specific value. An instance of the Random class will start from the initial value and update it every time you get a value from it. You do not need to worry about it.

If you see the code of the Random class, so they assign the seed for the first time:

 public Random() { this(seedUniquifier() ^ System.nanoTime()); } private static long seedUniquifier() { // L'Ecuyer, "Tables of Linear Congruential Generators of // Different Sizes and Good Lattice Structure", 1999 for (;;) { long current = seedUniquifier.get(); long next = current * 181783497276652981L; if (seedUniquifier.compareAndSet(current, next)) return next; } } 

So, you should leave the task just for that.

+1
source

This is the result of what we call them psuedorandom. There is a complex and, as a rule, irreversible, but still deterministic function for every random call; usually a simple-cellular automaton. The return of truth for many seeds of randomization is an artifact of this function; that you get something by accident, I suggest using a large and variant number, for example, from System.nanoTime ().

0
source

Source: https://habr.com/ru/post/984752/


All Articles