Home > Net >  Default algo for RandomGenerator (L32X64MixRandom) generates the same number each time
Default algo for RandomGenerator (L32X64MixRandom) generates the same number each time

Time:05-07

The default algo for RandomGenerator ie. L32X64MixRandom as of JDK 18 (available since 17), generates the same number each time on individual invocations.

jshell> java.util.random.RandomGenerator.getDefault().nextInt(100,999)
$10 ==> 526

jshell> java.util.random.RandomGenerator.getDefault().nextInt(100,999)
$11 ==> 526

jshell> java.util.random.RandomGenerator.of("L32X64MixRandom").nextInt(100, 999)
$14 ==> 526

jshell> java.util.random.RandomGenerator.of("L32X64MixRandom").nextInt(100, 999)
$15 ==> 526

neither does javadoc sound any special caution:

Returns a pseudorandomly chosen int value between the specified origin (inclusive) and the specified bound (exclusive).

Implementation Requirements: The default implementation checks that origin and bound are positive ints. Then invokes nextInt(), limiting the result to be greater that or equal origin and less than bound. If bound is a power of two then limiting is a simple masking operation. Otherwise, the result is re-calculated by invoking nextInt() until the result is greater than or equal origin and less than bound.

While other algos including legacy ones seem to have percieveable levels of randomness eg.

jshell> java.util.random.RandomGenerator.of("Random").nextInt(100,999)
$7 ==> 451

jshell> java.util.random.RandomGenerator.of("Random").nextInt(100,999)
$8 ==> 633

jshell> java.util.random.RandomGenerator.of("L64X128MixRandom").nextInt(100, 999)
$12 ==> 570

jshell> java.util.random.RandomGenerator.of("L64X128MixRandom").nextInt(100, 999)
$13 ==> 844

Is there a reason for this level of determinism with the default choice?

EDIT: behaviour wrt. streams is pretty similar, the initial value always seem to be the same

jshell> java.util.random.RandomGenerator.getDefault().ints(100,999).limit(5).toArray()
$22 ==> int[5] { 526, 860, 258, 558, 820 }

jshell> java.util.random.RandomGenerator.getDefault().ints(100,999).limit(5).toArray()
$23 ==> int[5] { 526, 866, 448, 654, 684 }

CodePudding user response:

This is a bug listed at https://bugs.openjdk.java.net/browse/JDK-8282551

It is shown as fixed in Java 19, and there's a backport request to Java 17 and 18 (https://bugs.openjdk.java.net/browse/JDK-8284185 resolved 4/1/2022), but it's not clear when the backported fix will appear.

While this is a link-only answer, I believe it is appropriate because others will be encountering this bug and searching here.

  • Related