2013-03-10 33 views
0

我想要一個從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]); 

    } 

現在奇怪的是,0和3擊中了大約一半的時間1和2擊中,這怎麼可能?

+3

四捨五入。從0到0.5變爲0 - 從2.5到3變成3. 1.5到2.5是間隔的兩倍,因此被擊中的可能性是兩倍。統一的結果使用'floor'而不是'round'。 – Floris 2013-03-10 04:40:49

+4

我自己,我會使用Random類的'nextInt(4)'方法。 – 2013-03-10 04:41:46

+0

謝謝你們!爲解釋和如何改變它。 – Tricky 2013-03-10 04:47:14

回答

2

http://docs.oracle.com/javase/6/docs/api/java/lang/Math.html#round(double)

返回最接近參數的long。結果通過加1/2來四捨五入爲整數,取結果的底部,並將結果轉換爲長整型。

您正在創建不等尺寸的桶:

0 - 0.4999 ... => 0(0.5)

0.5 - 1.499 ... => 1(1)

1.5 - 2.499 ... => 2(1)

2.5 - 2.99999 ... => 3(0.5)

要修正,無論是使用:

Random.nextInt(4); 

呃......錯字,感謝@TedHopp - 我的意思是:

Random r = new Random(); 
... 
r.nextInt(4); 

或做

(int) (Math.random() * 4);s 

哪會做你的期望。

+0

或者更好,創建一個'java.util.Random'對象並使用'nextInt(4)'。 – 2013-03-10 04:46:19

+0

注意Math.random(),它永遠不會等於1.00。這意味着在轉換爲int時,假設'Math.random()* n',最大值爲n-1。 – 2013-03-10 04:51:09

+0

@Legend的確 - 這就是爲什麼當我查找範圍從0到3時,設置n = 4。 – James 2013-03-10 06:12:20

1

發生這種情況是因爲你四捨五入。 0只能小於0.5才能四捨五入。但是如果它在0.5和1.5之間,可以選擇1。因此給它兩次發生的機會。同樣的事情發生在2,1.5和2.5之間。而3只從2.5到3

6

看那個四捨五入到每個整數區間:

|----+----|----+----|----+----| 
0   1   2   3 

<...> 
Rounds to 0 
    <........> 
    Rounds to 1 
       <........> 
       Rounds to 2 
         <....> 
         Rounds to 3 

你可以看到,這一輪以0-3的範圍內是成功的一半大小爲別人,所以如果你選擇統一的話,你可以將它們擊中一半。

1
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; 

使用小區,而不是圓提供了更好的分配:

250 
239 
242 
269