返回课程

从 min 到 max 的随机整数

重要性: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) );

另一种方法是使用Math.floor对从minmax+1的随机数进行取整。

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

所有区间长度相同,使得最终分布均匀。