随机数,Math.floor(...) vs Math.ceil(...)

dop*_*umi 5 javascript random

我见过很多生成随机数的代码,例如

// random integers in the interval [1, 10]
Math.floor(Math.random()*10 + 1)
Run Code Online (Sandbox Code Playgroud)

无论如何,我觉得我错过了一些东西。为什么人们不使用更简洁的方式

Math.ceil(Math.random()*10);
Run Code Online (Sandbox Code Playgroud)

?

我试图测试随机性,到目前为止似乎是正确的。

其实后面的代码

// will generate random integers from 1 to 4
var frequencies = [ 0, 0, 0, 0, 0 ]; // not using the first place
var randomNumber;
for ( var i = 0; i < 1*1000*1000; ++i ) {
   randomNumber = Math.ceil(Math.random()*4);
   frequencies[randomNumber]++;
}

for ( var i = 1; i <= 4; ++i ) {
   console.log(i +": "+ frequencies[i]);
}
Run Code Online (Sandbox Code Playgroud)

打印出来

1: 250103
2: 250161
3: 250163
4: 249573
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

Quick OT:有没有更简洁的方法来声明和初始化频率?我的意思是像frequencies[5] = { 0 };来自 C++...

fca*_*ran 7

如在所述MDN参考关于Math.random()

返回 [0, 1) 范围内的浮点伪随机数,即从 0(含)到但不包括 1(不含),然后您可以将其缩放到所需的范围。

由于 Math.random 可以返回0,那么Math.ceil(Math.random()*10)也可以返回0并且该值超出了您的[1..10]范围。


关于您的第二个问题,请参阅创建零填充 JavaScript 数组的最有效方法?

  • @FabrizioCalderan 可以证实墨菲定律。我刚刚有一个已经可靠工作了几个月的 Node.js 包,在向我的团队演示一个不相关的新功能时,失败了,出现了前所未有的错误,因为 Math.random() 选择了 *那个* 时刻返回 `0`第一次。经验教训:如果在某个功能中使用 Math.random(),请对其进行测试,针对不同值的数组运行它来代替随机值,并在该数组中包含“0” (2认同)

Ja͢*_*͢ck 6

Math.floor()由于 的范围,这里是首选Math.random()

例如,Math.random() * 10给出 的范围[0, 10)。使用Math.floor()永远不会得到 的价值10,而Math.ceil() 可能会得到0