A few members of our community have been studying the latest snapshot code and they claim to have found an issue in the class LegacyRandomSource
.
Java documentation specifies that Next(bits)
should return (int)(seed >>> (48 - bits))
. However, current code seems to return (int)(seed >> (48 - bits))
.
This could cause future issues related to nextInt
returning negative numbers in rare cases, and incomplete parity with Bedrock.
Members that confirmed this issue in our community: cortex and MrSpike.
Attachments
Comments 8
Using this code, it's possible to see that Mojang's implementation does not produce the same results as Java's default implementation (which would be the results produced in Bedrock editions):
Seed: 4398074666259 | Java: 30 | Mojang: 19
Seed: 39032724456376 | Java: 50 | Mojang: 9
Seed: 39032784013762 | Java: 47 | Mojang: 13
Seed: 39032805695460 | Java: 12 | Mojang: 17
Seed: 11613744092361 | Java: 5 | Mojang: 2
Seed: 165764713 | Java: 12 | Mojang: 2
Seed: 11613765769747 | Java: 2 | Mojang: 6
Seed: 223209395 | Java: 9 | Mojang: 6
This issue isn't relevant anymore, as LegacyRandomSource is not being used in any important place of the game anymore, except for stronghold layouts, which can't be affected by that problem. (Mojang switched to XoroShiro128++ for features in pre-release 1)
It looks like LegacyRandomSource
is still used (MC-249933).
Mojang's code in `next` looks like this:
public int next(int i) {
long m;
long l = this.seed.get();
if (!this.seed.compareAndSet(l, m = l * 25214903917L + 11L & 0xFFFFFFFFFFFFL)) {
throw ThreadingDetector.makeThreadingException("LegacyRandomSource", null);
}
return (int)(m >> 48 - i);
}
So isn't `m` always positive here? I don't see where the difference between >> and >>> in this case
I cannot reproduce using MC@h Matt 's repro instructions. I can only assume that their JavaRnd implementation is not equivalent to Mojang's RandomSource, or maybe that Mojang fixed it since the issue was reported. Here's the code I ran using Mojang's actual RandomSource:
Random rand = new Random(4398074666259L);
System.out.println(rand.nextInt(53));
RandomSource rand2 = RandomSource.create(4398074666259L);
System.out.println(rand2.nextInt(53));
And the output:
30
30
I think this issue can be closed.
For reference, https://docs.oracle.com/javase/8/docs/api/java/util/Random.html#next-int- specifies >>> (logical shift operation) usage.