从 min 到 max 的随机整数
重要性:2
创建一个函数 randomInteger(min, max)
,该函数生成一个从 min
到 max
的随机整数,包括 min
和 max
作为可能的值。
区间 min..max
中的任何数字都必须以相同的概率出现。
工作示例
alert( randomInteger(1, 5) ); // 1
alert( randomInteger(1, 5) ); // 3
alert( randomInteger(1, 5) ); // 5
您可以使用上一个任务的解决方案作为基础。
简单但错误的解决方案
最简单但错误的解决方案是生成一个从 min
到 max
的值并将其四舍五入
function randomInteger(min, max) {
let rand = min + Math.random() * (max - min);
return Math.round(rand);
}
alert( randomInteger(1, 3) );
该函数可以运行,但结果不正确。获取边缘值min
和max
的概率是其他值的二分之一。
如果您多次运行上面的示例,您会很容易发现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.5
到3.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
对从min
到max+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
所有区间长度相同,使得最终分布均匀。