java.util.Random中的181783497276652981
偶然间看到Random类的构造函数中有181783497276652981
这么一个Magic Number, 没有定义为常量, 也没有对这个数做什么特别的说明, 感觉很奇怪, 于是好奇心驱使我扒一扒这个数字的由来:
// java version: 1.8.0_251
public class Random implements java.io.Serializable {
// ...
/**
* The internal state associated with this pseudorandom number generator.
* (The specs for the methods in this class describe the ongoing
* computation of this value.)
*/
private final AtomicLong seed;
/**
* 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);
// ...
}
References:
- https://stackoverflow.com/questions/18092160/whats-with-181783497276652981-and-8682522807148012-in-random-java-7 一些讨论
- http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.99.6553&rep=rep1&type=pdf 线性同余发生器对应的文章
- https://bugs.openjdk.java.net/browse/JDK-8201634# openjdk的bug报告
根据openjdk的报告, 这个数字是由于疏忽导致漏了一位, 而且这个数确实来源于线性同余发生器文章中,在Java 11中被修复。
于是我就顺手找了下jdk 11的代码:
确实修复了,这个数字不一样没有什么太大的影响,只不过文章中给出的原始数字更好而已。至于另一个数8682522807148012
,看起来似乎是随机的,可能是这段代码写的时候的System.nanoTime()
也说不好啊,哈哈。