【发布时间】:2013-11-19 00:20:19
【问题描述】:
我想知道 Java 中 Math.random() 后面的 PRNG* 的默认种子是什么。据我了解,C 中的一个是基于系统时钟的。那么它在Java中是否相似?另外,每次调用Math.random() 时,种子是否都会改变?
*PRNG = 伪随机数生成器
【问题讨论】:
我想知道 Java 中 Math.random() 后面的 PRNG* 的默认种子是什么。据我了解,C 中的一个是基于系统时钟的。那么它在Java中是否相似?另外,每次调用Math.random() 时,种子是否都会改变?
*PRNG = 伪随机数生成器
【问题讨论】:
如果你Read The Fine Manual 它会告诉你
当这个方法第一次被调用时,它会创建一个新的 伪随机数生成器,就好像通过表达式
new java.util.Random()使用了这个新的伪随机数生成器 此后用于对该方法的所有调用,并且不会在其他任何地方使用。
跟进java.util.Random(),文档说
public Random()创建一个新的随机数生成器。此构造函数设置种子 随机数生成器的值很可能是不同的 从此构造函数的任何其他调用。
当前的实现似乎基于System.nanoTime(),但可能会发生变化,但仍符合文档合同。
至于每次调用都更改种子,这不是种子的工作方式。 PRNG 被播种一次,然后产生从该初始状态演变而来的一系列值。您不应该,Java 也不会,继续重新播种。
【讨论】:
rand.setSeed(System.currentTimeMillis( ));的东西表示这个语句使用当前时间作为种子,那么如果当前时间是20:01,那么种子或起始值将是20还是01?还是 2001 年?
您可以随时阅读code。
Math.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);
【讨论】:
正如您在 documentation 上看到的那样,该函数使用一个名为 Random() 的类,它使用 48 位种子,并生成均匀分布。
【讨论】: