开发者

Random numbers and floor vs round function

Why if I use random number generator and range 0 - 9 I don't get the same uniform distributi开发者_开发问答on as combined it with the floor function?


Math.floor(Math.random() * 10) gives quite uniform distribution, while Math.round(Math.random() * 10) doesn't.

Math.floor() returns 0 for any value in the range [0, 1) (1 exclusive), 1 for any value in the range [1, 2), etc.

So if we have equal chances of getting a number in one of these ranges, we will get an equal distribution of 0's and 1's.

Math.round(), however, returns 0 for values under 0.5, 1 for values under 1.5, etc.

So we actually have half the chances of getting a 0, as only values from 0 to 0.5 will round to 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 ║
╚═════════╩═════════╩═════════╝


I really like to trigger 31-bit int instead of Math.floor(), by doing a binary "or 0" operation. It makes it slightly faster (stack vs heap,) seems a tad neater, and does the same thing, in a practical sense. Here is an example that gets a random element of an array:

var ar=[1,2,3,4,5,6,7,8,9,0,'a','b','c','d']
console.log(ar[(Math.random() * ar.length) |0])

This might seem like premature optimization, but as I said, I like how it looks, and it takes less typing than Math.floor(). Using Math.round() would require an extra step (because the spread is 1 to ar.length not 0 to ar.length-1)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜