为何生成随机数时使用Math.floor()而非Math.round()或Math.ceil()
为什么生成随机数时用Math.floor()而非Math.round()或Math.ceil()
先明确前提:Math.random() 返回的是一个 大于等于0,小于1 的伪随机数,记为 r,即 0 ≤ r < 1。
我们以你例子里的 *4 为例,分别分析三种方法的差异:
1. Math.floor(r * 4) 的效果
r * 4 的范围是 0 ≤ r*4 < 4,经过 Math.floor() 向下取整后:
[0,1)→ 0[1,2)→ 1[2,3)→ 2[3,4)→ 3
每个数值对应的区间长度都是1,因此0、1、2、3四个数的概率完全均等,都是25%,这正是大多数场景需要的「均匀分布随机整数」。
2. Math.ceil(r * 4) 的问题
r *4 的范围是 0 ≤ r*4 <4,Math.ceil() 向上取整后:
- 只有当
r*4=0(也就是r=0)时,结果是0,但Math.random()返回0的概率极低(几乎可以忽略); - 其余情况:
(0,1)→1,[1,2)→2,[2,3)→3,[3,4)→4。
这会导致两个问题:
- 如果你需要的是0-3的随机数,这个方法给出的是1-4,范围完全不符合预期;
- 就算你调整为
Math.ceil(r*4)-1来凑0-3,也会存在极小概率得到-1(当r=0时),引发bug。
3. Math.round(r *4) 的问题
r*4 的范围是 0 ≤ r*4 <4,Math.round() 四舍五入后:
[0,0.5)→0[0.5,1.5)→1[1.5,2.5)→2[2.5,3.5)→3[3.5,4)→4
可以看到,0和4对应的区间长度只有0.5,而1、2、3对应的区间长度是1。这就导致0和4的概率只有12.5%,远低于1、2、3的25%,随机数的分布不均匀,不符合大多数场景的需求。
总结
如果需要生成 [min, max] 范围内的均匀分布随机整数,标准写法是:
Math.floor(Math.random() * (max - min + 1)) + min
它能保证每个数值的概率完全均等,且不会出现超出范围的异常值。
内容的提问来源于stack exchange,提问作者coolcoder71012
相关产品推荐
相关产品推荐

