我想知道Java中Math.random()
背后的PRNG(伪随机数生成器)的默认种子是什么。据我所知,C语言中的PRNG基于系统时钟。那么在Java中是类似的吗?此外,每次调用Math.random()
时种子是否会改变?
如果你阅读精细手册,它会告诉你:
当第一次调用此方法时,它会创建一个新的伪随机数生成器,就像表达式
new java.util.Random()
一样。此后,所有对此方法的调用都将使用此新的伪随机数生成器,并且不在其他地方使用。
接下来看看java.util.Random()
的文档:
public Random()
创建一个新的随机数生成器。此构造函数将随机数生成器的种子设置为一个值,该值非常可能与此构造函数的任何其他调用不同。
当前实现似乎基于System.nanoTime()
,但可能会更改并仍符合文档的约定。
至于每次调用都更改种子,这不是种子的工作方式。PRNG只有在最初进行种子处理之后才会产生一系列值。您不应该重新播种(Java也不会这样做)。
您可以随时阅读代码。
Math.random()
只是使用一个内部静态的Random对象,该对象没有实例化参数...
Random() {
90 this(seedUniquifier() ^ System.nanoTime());
91 }
92
93 private static long seedUniquifier() {
94 // L'Ecuyer, "Tables of Linear Congruential Generators of
95 // Different Sizes and Good Lattice Structure", 1999
96 for (;;) {
97 long current = seedUniquifier.get();
98 long next = current * 181783497276652981L;
99 if (seedUniquifier.compareAndSet(current, next))
100 return next;
101 }
102 }
103
104 private static final AtomicLong seedUniquifier = new AtomicLong(8682522807148012L);
rand.setSeed(System.currentTimeMillis( ));
这样的语句,它表示该语句使用当前时间作为种子,那么如果当前时间是20:01,那么种子或起始值将是20还是01?或者是2001? - AHF