为什么我使用随机数生成器并且范围为0 - 9我没有得到与将它与floor功能相结合的均匀分布?
答案 0 :(得分:26)
Math.floor(Math.random() * 10)
提供了非常均匀的分布,而Math.round(Math.random() * 10)
则没有。
Math.floor()为范围[0,1)中的任何值(1独占)返回0,对于范围[1,2]中的任何值返回1,等等。
因此,如果我们在这些范围之一中获得数字的机会相等,我们将得到0和1的平均分布。
然而,Math.round()对于低于0.5的值返回0,对于低于1.5的值返回1,等等。
所以我们实际上有一半的机会获得0,因为只有从0到0.5的值将舍入为0.
╔═════════╦═════════╦═════════╗
║ Range ║ floor() ║ round() ║
╠═════════╬═════════╬═════════╣
║ [0, 1) ║ 0 ║ 0 or 1 ║
║ [1, 2) ║ 1 ║ 1 or 2 ║
║ [2, 3) ║ 2 ║ 2 or 3 ║
║ ... ║ ... ║ ... ║
║ [9, 10) ║ 9 ║ 9 or 10 ║
╚═════════╩═════════╩═════════╝
答案 1 :(得分:2)
我真的想通过二进制"或0"来触发31位int而不是Math.floor()
。操作。它使得它稍微更快(堆栈与堆,)似乎有点整洁,并在实际意义上做同样的事情。下面是一个获取数组随机元素的示例:
var ar=[1,2,3,4,5,6,7,8,9,0,'a','b','c','d']
console.log(ar[(Math.random() * ar.length) |0])
这可能看起来像是过早的优化,但正如我所说的,我喜欢它的外观,而且输入的次数少于Math.floor()
。使用Math.round()
需要一个额外的步骤(因为点差为1
到ar.length
而不是0
到ar.length-1
)