Java 行为奇怪的随机数发生器

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

我想要一个从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.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