返回課程

從最小值到最大值之間的隨機整數

重要性:2

建立一個函式 randomInteger(min, max),用來產生一個隨機的整數,範圍從 minmax,包含 minmax 作為可能的值。

min..max 範圍內的任何數字都必須以相同的機率出現。

其工作範例

alert( randomInteger(1, 5) ); // 1
alert( randomInteger(1, 5) ); // 3
alert( randomInteger(1, 5) ); // 5

您可以使用前一個任務的解法作為基礎。

簡單但錯誤的解法

最簡單但錯誤的解法是從 minmax 產生一個值,並將其四捨五入

function randomInteger(min, max) {
  let rand = min + Math.random() * (max - min);
  return Math.round(rand);
}

alert( randomInteger(1, 3) );

這個函式運作正常,但並不正確。取得邊緣值 minmax 的機率比其他任何值低兩倍。

如果您多次執行上述範例,您會輕易發現 2 出現的頻率最高。

這是因為 Math.round() 從區間 1..3 取得亂數,並將其四捨五入,如下所示

values from 1    ... to 1.4999999999  become 1
values from 1.5  ... to 2.4999999999  become 2
values from 2.5  ... to 2.9999999999  become 3

現在我們可以清楚地看到 1 取得的次數是 2 的一半。3 也是如此。

正確的解法

有許多正確的解法。其中一種是調整區間邊界。為了確保區間相同,我們可以從 0.53.5 產生值,從而將所需的機率加入邊緣

function randomInteger(min, max) {
  // now rand is from  (min-0.5) to (max+0.5)
  let rand = min - 0.5 + Math.random() * (max - min + 1);
  return Math.round(rand);
}

alert( randomInteger(1, 3) );

另一種方法是對從 minmax+1 的亂數使用 Math.floor

function randomInteger(min, max) {
  // here rand is from min to (max+1)
  let rand = min + Math.random() * (max + 1 - min);
  return Math.floor(rand);
}

alert( randomInteger(1, 3) );

現在所有區間都以這種方式對應

values from 1  ... to 1.9999999999  become 1
values from 2  ... to 2.9999999999  become 2
values from 3  ... to 3.9999999999  become 3

所有區間都具有相同的長度,使最終分佈均勻。