Java 行为奇怪的随机数发生器
我想要一个从0到3的随机数,并尝试了下面的代码来看看它是如何工作的Java 行为奇怪的随机数发生器,java,random,Java,Random,我想要一个从0到3的随机数,并尝试了下面的代码来看看它是如何工作的 int[] count = new int[4]; for (int i = 0; i < 1000; i++) { int t = (int)(Math.round((Math.random() *3))); count[t] +=1; } for (int i = 0; i < count.length; i++) { System
int[] count = new int[4];
for (int i = 0; i < 1000; i++) {
int t = (int)(Math.round((Math.random() *3)));
count[t] +=1;
}
for (int i = 0; i < count.length; i++) {
System.out.println(count[i]);
}
int[]计数=新的int[4];
对于(int i=0;i<1000;i++){
int t=(int)(Math.round((Math.random()*3));
计数[t]+=1;
}
for(int i=0;i
奇怪的是,0和3的命中率大约是1和2命中率的一半,这怎么可能呢?这是因为你在取整。如果0小于0.5,则只能将其四舍五入。但是,如果1介于0.5和1.5之间,则可以选择1。因此给它两倍的发生机会。同样的情况也发生在2上,介于1.5和2.5之间。3只是从2.5到3。看看四舍五入到每个整数的间隔:
|----+----|----+----|----+----|
0 1 2 3
<...>
Rounds to 0
<........>
Rounds to 1
<........>
Rounds to 2
<....>
Rounds to 3
|----+----|----+----|----+----|
0 1 2 3
四舍五入到0
四轮到一轮
轮到2轮
四轮到三轮
您可以看到,四舍五入到0和3的范围是其他范围的一半,因此,如果您选择一致,则命中它们的频率是其他范围的一半。
返回与参数最接近的long。将结果四舍五入为整数,方法是将结果加1/2,以结果为底,并将结果强制转换为long类型
您正在创建大小不等的桶:
0-0.4999…=>0(.5)
0.5-1.499…=>1(1)
1.5-2.499…=>2(1)
2.5-2.99999…=>3(.5)
要修复此问题,请使用:
Random.nextInt(4);
呃。。。打字错误,谢谢@TedHopp-我是说:
Random r = new Random();
...
r.nextInt(4);
或者
这会实现你的期望
class Math {
...
public static long round(double a) {
return (long)floor(a + 0.5d);
}
...
}
命中1和2的概率更大
int t = (int)(Math.ceil((Math.random() * 4))) - 1;
使用ceil而不是round可以提供更好的分布:
250
239
242
269
四舍五入。从0到0.5变为0-从2.5到3变为3。1.5到2.5的间隔是两倍宽,因此被击中的可能性是两倍。使用
floor
而不是round
来获得统一的结果。我自己会使用随机类的nextInt(4)
方法。谢谢大家!对于解释以及如何更改它。或者更好,请创建一个java.util.Random
对象,并使用nextInt(4)
。注意,对于Math.Random(),它永远不会等于1.00。这意味着当强制转换为int时,最大值是n-1,假设Math.random()*n
@Legend确实如此-这就是为什么我在寻找从0到3的范围时设置n=4。@TedHopp-bah-这就是我的意思。我写的东西既不存在也没有意义。我在为@Tricky做符号,以防万一他想知道:)
250
239
242
269