Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java.Random.nextInt()中令人费解的行为_Java - Fatal编程技术网

Java.Random.nextInt()中令人费解的行为

Java.Random.nextInt()中令人费解的行为,java,Java,我正在实现一个SkipList。在算法中的某一点上,我们要掷硬币,反复做一些事情,只要它一直朝着正面,一旦我们看到反面就停止。我让奇数代表“头”,方法是: while (R.nextInt() % 2 == 1) 但这只在大约25%的时间里(在50000个ish电话中)产生了一个人头。改成 while (R.nextBoolean()) 正如预期的那样,有一半的时间产生头部。R被实例化为一个随机变量,以System.currentTimeMillis()作为种子。看来随机产生的比特流毕竟不是

我正在实现一个SkipList。在算法中的某一点上,我们要掷硬币,反复做一些事情,只要它一直朝着正面,一旦我们看到反面就停止。我让奇数代表“头”,方法是:

while (R.nextInt() % 2 == 1)
但这只在大约25%的时间里(在50000个ish电话中)产生了一个人头。改成

while (R.nextBoolean())
正如预期的那样,有一半的时间产生头部。R被实例化为一个随机变量,以System.currentTimeMillis()作为种子。看来随机产生的比特流毕竟不是均匀分布的。还有谁见过这种行为吗

我也尝试过:

while (Math.random() >= 0.5)
得到了我所期待的50/50(给予或接受)的行为

它似乎也适用于:

while (R.nextInt(2) == 1)
它似乎在接近一半的时间里都不会生成LSB为0的32位整数。看起来,在比特级别,我们也应该能够期望随机性。也许他们使用的是线性同余;也许我遗漏了什么,但这似乎是个问题。我意识到有“更好”的PRNG可用,我已经有了一些完全可行的解决方案;我只是想报告我观察到的情况

nextInt()
返回此随机数生成器序列中的下一个伪随机、均匀分布的int值

整数类型在Java中是有符号的,执行模运算
2
的可能结果是:
-1
(负奇数)、
0
(偶数)、
1
(正奇数)

nextInt()%2
仅对正奇数整数等于
1
,这就是为什么只有25%。您需要在条件上做一些小的改变:

 while (R.nextInt() % 2 != 0)
在Java
(n*2+1)中,如果
n
为负,则2
为-1。(这很烦人,因为它在数学上没有多大意义,但它就是这样。然而,它与
/
操作符的工作方式是一致的,所以
(a/b)*b+(a%b)=a
对于所有
a
b
而言,除非发生整数溢出。)

由于
Random.nextInt()
返回一个带符号的随机数,因此模将为0 50%的时间,-1 25%的时间和1 25%的时间


当然,您可以切换到
r.nextInt()%2!=0
r.nexttint()==0
但最具可读性的解决方案实际上只是使用
r.nextBoolean()

有趣——我认为%总是产生介于0和(模数-1)之间的值(即任何mod 5都必须是0-4,包括在内)。我确实尝试过使用
while((R.nextInt()&1)==1)
,而且似乎也像预期的那样工作。@user8887287如果需要,请使用Math.floorMod。