为什么Random.nextLong不会在Java中生成所有可能的长值?

时间:2014-03-25 18:10:55

标签: java random

Random类的nextLong()方法的Javadoc声明了

  

由于Random类使用的种子只有48位,因此该算法不会返回所有可能的长值。 (Random javadoc

实施是:

return ((long)next(32) << 32) + next(32);

我看到它的方式如下:为了创建任何可能的长,我们应该生成具有相同似然性的64位的任何可能的位模式。假设对next(int)的调用给出了32个随机位,那么这些位的串联将是64个随机位的序列,因此我们生成具有相等似然性的每个64位模式。因此,所有可能的长值。

我认为编写javadoc的人知道的更好,我的推理在某种程度上是有缺陷的。任何人都可以解释我的推理在哪里是不正确的,那么将返回什么样的多头?

3 个答案:

答案 0 :(得分:4)

由于Random是伪随机的,我们知道给定相同的种子它将返回相同的值。按照他们的话来说,有48位的种子。这意味着最多可以打印出2 ^ 48个唯一值。如果还有更多意味着我们之前在位置上使用的某些值&lt; 2 ^ 48这次给我们的价值与上次不同。

如果我们尝试加入两个结果,我们会看到什么?

|a|b|c|d|e|f|...|(2^48)-1|

以上是一些价值观。有多少对? a-b,b-c,c-d,......(2 ^ 48)-1-a。还有2 ^ 48对。我们不能仅用2 ^ 48对填充2 ^ 64的所有值。

答案 1 :(得分:0)

伪随机数发生器就像巨大的数字环。你从某个地方开始,然后一步一步地移动环,就像你拉出数字一样。这意味着对于给定的种子 - 初始内部状态 - 所有后续数字都是预先确定的。因此,由于内部状态仅为48位宽,因此只有2到48个随机数。因此,由于下一个数字是由前一个数字给出的,现在很清楚为什么nextLong的实现不会生成所有可能的长值。

答案 2 :(得分:0)

让我们说一个完美的伪随机K比特生成器是在2 ^ K trys中创建所有可能的2 ^ K种子值的生成器。我们不能做得更好,因为只有2 ^ K个状态,并且每个状态由先前状态完全确定并确定自己是下一个状态。

假设我们以二进制形式写下48位发生器的输出。我们得到2 ^ 48 * 48位。 现在我们可以准确地说出我们可以通过列表获得多少64位序列并注意接下来的64位(在需要时包装到开头)。这正是我们拥有的位数:13510798882111488。 即使我们假设所有这些64位序列都是成对不同的(这一点都不明显),我们还有很长的路要走,直到2 ^ 64:18446744073709551616。

我再次写下数字:

18446744073709551616 pairwise different 64 bit sequences we need
   13510798882111488 64 bit sequences we can get with a 48 bit seed.

这证明了javadoc作家是对的。使用随机生成器

只能生成所有长值的1/1844