【问题标题】:Why JavaScript Math.random() returns same number multiple times为什么 JavaScript Math.random() 多次返回相同的数字
【发布时间】:2019-01-04 22:57:24
【问题描述】:

我有一个包含两个项目的数组,我需要随机选择这些项目,但大多数时候我从数组中得到相同的项目...

查看代码:

var numbers = Array(523,3452);
var choice = numbers[Math.floor(Math.random()*numbers.length)];
console.log("Choice:", choice);

如何避免这种行为?

【问题讨论】:

  • Uncaught ReferenceError: groups is not defined
  • 你知道Array(523, 3452) 就是[523, 3452] 吗?因此,您可能需要多次尝试才能获得另一个号码。
  • @ibrahimmahrir 怎么会这样?该代码完全按预期工作。没有问题,但 OP 声称有一个。
  • 无法复制。 Math.random,在我知道的所有实现中,都通过了简单的统计测试。因此,它不会在正常应用程序中偏向于任何一种选择。
  • @ibrahimmahrir 你为什么这么认为?他的开场白是“我有一个包含两个项目的数组”。

标签: javascript node.js math


【解决方案1】:

随机数可以出现条纹;这是随机的一部分。但随着时间的推移,law of large numbers 应该会接管并消除这些条纹。您可以通过多次运行并计数来轻松测试:

var numbers = Array(523,3452);
let counts = [0,0]

for (let i = 0; i < 10000; i++) {
    let choice = numbers[Math.floor(Math.random()*numbers.length)];
    if (choice ===  523) counts[0]++
    else if (choice == 3452) counts[1]++
}

// counts should be about even
console.log(counts);

【讨论】:

  • 随机数可以出现条纹;这是随机性的一部分。 - 有时喜欢向企业解释这一点。
  • 我的第一次运行他们都是5000
  • 哇,您实际上可以为此获得reversal 徽章。
  • @GetOffMyLawn 嗯,恰好得到 5000 是一个相当低的概率事件......如果我没记错的话,它是 (10000 选择 5000)/2^10000 似乎大约是 8e- 3.
【解决方案2】:

Math.random() 函数返回一个在 0-1 范围内(包括 0,但不包括 1)的浮点伪随机数,在该范围内具有近似均匀的分布 - 然后您可以将其缩放到您想要的范围.

Math.random() * 2 将给出 0 到 1.99999999999999 的范围,但不是 2。Math.floor(0...1.999999999999) 将返回 0 或 1,有 50% 的机会类似于硬币。

numbers[0] 将给出 523,numbers[1] 将给出 3452

【讨论】:

    【解决方案3】:

    我认为这是一次有趣的尝试,但 Math.Round() 更糟。我只是想在 2 到 12 之间做随机数,80% 的时间是奇数。

    使用Math.Floor(),您可以获得这些连胜,但这不仅仅是几率的连胜。我会得到 2 到 12 之间的任意数量的条纹,这样更好。

    【讨论】:

      【解决方案4】:

      不要使用Math.floor(),而是使用Math.round()

      它不会完全解决问题,但会降低获得相同数字的机会,因为使用Math.floor(),任何十进制小数都将以其最小的整数返回,即使该数字是1.99它将返回1 而不是2,因为它靠近2

      但是使用Math.round(),您将始终得到更接近小数的整数,即1.66 将返回2,而1.44 将返回1

      【讨论】:

      • 无法完美运行。有时它会返回 undefined。
      • 这是不正确的。由于 0 索引,向上舍入到 2 将为您提供 numbers[2],即 undefinednumbers[0]numbers[1] 是唯一有效的值,因为数组的长度为 2)。
      猜你喜欢
      • 2021-03-24
      • 1970-01-01
      • 2011-04-15
      • 2011-05-26
      • 1970-01-01
      • 1970-01-01
      • 2015-09-29
      • 2021-05-26
      • 2015-05-18
      相关资源
      最近更新 更多