【问题标题】:Why isn't Math.floor((Math.random() * 999999) + 100000) reliable for producing 6 digit numbers?为什么 Math.floor((Math.random() * 999999) + 100000) 不能可靠地生成 6 位数字?
【发布时间】:2014-08-04 15:21:39
【问题描述】:

我查看了其他一些问题,但它们都脱节了,confusing 的答案。

我想要一个随机的 6 位数字,这个脚本在大多数情况下都可以工作 - 但是它也会在大约 20% 的情况下产生 7 位数字。

Math.floor((Math.random() * 999999) + 100000)

我的问题:

  1. 为什么?
  2. 避免这种情况的正确方法是什么?

请不要建议使用 substring 或类似的东西,因为它有点 hack

【问题讨论】:

  • 应该只做 1/10 的时间
  • 编写一个通用的randInt 方法并使用它而不是内联算术可能会有所帮助。你可以找到一个示例实现here
  • @Alnitak 与所有好事一样,我目前认为我的 20% 有点慷慨,更像是我上次运行的 40%:/
  • @tim.baker 它真的应该只有 10%(假设正确的随机分布)。您的范围的随机部分是 0..999,998 而不是 0..899,999,因此只有当您达到超过 900,000 的位(应该是样本的 10%)时,您才会最终得到七位数。

标签: javascript math random


【解决方案1】:

这是一个简单的计算范围错误。注意:下面的文字使用[] 表示包含 范围,() 表示排除 范围。

要获得范围 [100000, 999999],它在整数数学中相当于 [100000, 1000000),您需要获取范围 [0, 900000) 中的数字,然后加上 100000,例如

Math.floor(900000 * Math.random()) + 100000

因子是 900000 而不是 899999,因为 Math.random() 函数产生的数字在 [0, 1) 范围内,即不包括 1 本身。

【讨论】:

  • 应该注意的是,许多 JavaScript 引擎中的随机数生成器并不是那么好。这里有一个流行的替代品:github.com/davidbau/seedrandom
【解决方案2】:

问题出在你的数学上。

Math.random 产生一个从 0.0 到 1.0 的浮点数。在最坏的情况下,您将 1.0 与 999999 相乘并再加上 100000 。这导致 1099999.0(对于最大的情况)。

此行应始终生成一个 6 位数字

Math.floor((Math.random() * 899999) + 100000)

【讨论】:

  • 你的数学也有问题 - OP 原始代码的最大值是 1,099,998 ... ;-)
  • 啊!不过我看不到...?
  • @Alnitak 不,不是。在 JS 控制台中输入 Math.floor(1 * 999999 + 100000)
  • @MikeC 这就是问题所在 - 根据定义,Math.random() 永远不会产生精确的 1.0
  • 而且乘法因子也是错误的(我之前没有发现!)出于同样的原因,它是 900000,而不是 899999
猜你喜欢
  • 2015-09-29
  • 2011-12-21
  • 1970-01-01
  • 2014-05-07
  • 2012-03-21
  • 1970-01-01
  • 2011-11-18
  • 1970-01-01
相关资源
最近更新 更多