当我在Eclipse中查看源代码时,next
的{{1}}方法基本上是:
java.util.Random
如何确定不同的JDK或JVM是以不同的方式或使用不同的常量实现seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
return (int)(seed >>> (48 - bits));
?
我已经在Weird behaviour when seeding Java Random中遇到了不同的无参数构造函数。我想知道next
方法是否会发生类似的事情。我在哪里可以找到不同实现的来源?
答案 0 :(得分:5)
Random.next()
的Javadoc明确说明了使用哪种算法生成下一个数字。
理论上可能不同的JVM可能使用不同的算法,但这不太可能,特别是如果您将自己限制为基于Sun / Oracle库的JVM。
该文档是否必然适用于所有JDK?
你需要检查以确定,但可能是的。这是Sun / Oracle不太可能改变的事情,因为有可能破坏过去15年左右的大量现有Java应用程序和测试套件。
以下是一些事实:
Java 1.3.1到Java 1.7(*)的javadoc包含与此方法完全相同的规范,
如果符合规范,则只允许使用商标“Java”
大多数(如果不是全部)Java(TM)实现使用派生自Oracle / Sun源代码的类库,
开发人员会注意到使用了不同的算法......并大声抱怨。
因此,使用不同算法实现Java(TM)的可能性非常小。
(*我在网上找不到Java 1.1 javadocs,但我期待他们会说同样的话。)
答案 1 :(得分:4)
如何确定不同的JDK或JVM是否会以不同的方式或使用不同的常量实现?
通过在不同JVM上的程序中使用相同的种子,并查看是否获得相同的序列,因为序列对于给定的种子是确定性的。
我不确定JDK是否可以使用不同的算法,因为documentation for next
说:
方法
next
由类Random
通过原子方式更新种子来实现
(seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1)
并返回
(int)(seed >>> (48 - bits)).
这是一个线性同余伪随机数发生器,由DH Lehmer定义并由Donald E. Knuth在计算机编程艺术,第3卷: Seminumerical Algorithms 中描述,第3.2.1节。
......这似乎设定了一个特定的合同,虽然就在它之前它说
next
的一般合同是它返回int
值,如果参数bits
介于1
和32
之间(包括),那么返回值的许多低位将是(近似)独立选择的位值,每个位值(大致)可能是0
或1
。
...也许这样就可以让算法摆脱困境。
我在哪里可以找到不同实现的来源?
如果它们是开源的,大概你可以在项目的回购中找到实现。如果他们关闭了,那么......