Java中的默认种子伪随机数生成器

6

我想知道Java中Math.random()背后的PRNG(伪随机数生成器)的默认种子是什么。据我所知,C语言中的PRNG基于系统时钟。那么在Java中是类似的吗?此外,每次调用Math.random()时种子是否会改变?

3个回答

7

如果你阅读精细手册,它会告诉你:

当第一次调用此方法时,它会创建一个新的伪随机数生成器,就像表达式

new java.util.Random()

一样。此后,所有对此方法的调用都将使用此新的伪随机数生成器,并且不在其他地方使用。

接下来看看java.util.Random()的文档:

public Random()

创建一个新的随机数生成器。此构造函数将随机数生成器的种子设置为一个值,该值非常可能与此构造函数的任何其他调用不同。

当前实现似乎基于System.nanoTime(),但可能会更改并仍符合文档的约定。

至于每次调用都更改种子,这不是种子的工作方式。PRNG只有在最初进行种子处理之后才会产生一系列值。您不应该重新播种(Java也不会这样做)。


如果我们使用类似 rand.setSeed(System.currentTimeMillis( )); 这样的语句,它表示该语句使用当前时间作为种子,那么如果当前时间是20:01,那么种子或起始值将是20还是01?或者是2001? - AHF
2
@AHF Javadocs 是你的好朋友。 - pjs

4

您可以随时阅读代码

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);

-1
正如您可以在文档上看到的那样,该函数使用一个名为Random()的类,它使用48位种子并生成均匀分布。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接