Why were 181783497276652981
and 8682522807148012
chosen in Random.java
?
Here's the relevant source code from Java SE JDK 1.7:
/**
* Creates a new random number generator. This constructor sets
* the seed of the random number generator to a value very likely
* to be distinct from any other invocation of this constructor.
*/
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;
}
}
private static final AtomicLong seedUniquifier
= new AtomicLong(8682522807148012L);
So, invoking new Random()
without any seed parameter takes the current "seed uniquifier" and XORs it with System.nanoTime()
. Then it uses 181783497276652981
to create another seed uniquifier to be stored for the next time new Random()
is called.
The literals 181783497276652981L
and 8682522807148012L
are not placed in constants, but they don't appear anywhere else.
At first the comment gives me an easy lead. Searching online for that article yields the actual article. 8682522807148012
doesn't appear in the paper, but 181783497276652981
does appear -- as a substring of another number, 1181783497276652981
, which is 181783497276652981
with a 1
prepended.
The paper claims that 1181783497276652981
is a number that yields good "merit" for a linear congruential generator. Was this number simply mis-copied into Java? Does 181783497276652981
have an acceptable merit?
And why was 8682522807148012
chosen?
Searching online for either number yields no explanation, only this page that also notices the dropped 1
in front of 181783497276652981
.
Could other numbers have been chosen that would have worked as well as these two numbers? Why or why not?