Mozilla 开发者网络页面上有一些示例:
/**
* Returns a random number between min (inclusive) and max (exclusive)
*/
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
/**
* Returns a random integer between min (inclusive) and max (inclusive).
* The value is no lower than min (or the next integer greater than min
* if min isn't an integer) and no greater than max (or the next integer
* lower than max if max isn't an integer).
* Using Math.round() will give you a non-uniform distribution!
*/
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
这是其背后的逻辑。这是一个简单的三条规则:
Math.random()
返回Number
介于 0(包含)和 1(不包含)之间的值。所以我们有一个这样的区间:
[0 .................................... 1)
现在,我们想要一个min
介于(包含)和max
(不包含)之间的数字:
[0 .................................... 1)
[min .................................. max)
我们可以使用 来Math.random
获取 [min, max) 区间内的对应项。但是,首先我们应该通过min
从第二个区间中减去一点来解决这个问题:
[0 .................................... 1)
[min - min ............................ max - min)
这给出:
[0 .................................... 1)
[0 .................................... max - min)
我们现在可以申请Math.random
然后计算对应的。让我们选择一个随机数:
Math.random()
|
[0 .................................... 1)
[0 .................................... max - min)
|
x (what we need)
因此,为了找到x
,我们会这样做:
x = Math.random() * (max - min);
不要忘记加min
回来,这样我们就得到了 [min, max) 区间内的数字:
x = Math.random() * (max - min) + min;
这是 MDN 的第一个功能。第二个返回介于min
和之间的整数max
(包含两者)。
现在要获取整数,您可以使用round
,ceil
或floor
。
您可以使用Math.round(Math.random() * (max - min)) + min
,但这会产生不均匀的分布。两者都有,min
并且max
只有大约一半的机会滚动:
min...min+0.5...min+1...min+1.5 ... max-0.5....max
└───┬───┘└────────┬───────┘└───── ... ─────┘└───┬──┘ ← Math.round()
min min+1 max
如果将max
其排除在间隔之外,则滚动的机会甚至比 还要小min
。
这样Math.floor(Math.random() * (max - min +1)) + min
你就有了一个完美均匀的分布。
min... min+1... ... max-1... max.... (max+1 is excluded from interval)
└───┬───┘└───┬───┘└─── ... ┘└───┬───┘└───┬───┘ ← Math.floor()
min min+1 max-1 max
您不能在该等式中使用ceil()
and ,因为现在滚动的机会稍少,但您也可以滚动(不需要的)结果。-1``max``min-1