【问题标题】:Math.random() - Not random [closed]Math.random() - 不是随机的[关闭]
【发布时间】:2010-12-30 15:53:33
【问题描述】:

我创建了一个 jQuery 插件但我有一个问题,我使用以下代码:

Math.floor(Math.random()*500)

我将结果添加到一个元素, 但奇怪的是结果每次都一样。

如果我在生成随机数之后向该行添加一个 alert(), 我得到随机值,为什么? 我想得到没有 alert() 随机整数。但是怎么做呢?

【问题讨论】:

  • 我正在 Firebug 的 JavaScript 控制台中尝试您的代码,但每次都得到不同的数字。你使用的是什么浏览器?你能发布完整的代码吗? (即包括将结果添加到元素)。
  • 至少,你每次得到的结果是什么
  • 你能把你插件的代码贴出来吗?,这听起来像一个闭包问题...
  • 我看到在非常紧凑的循环中调用时会发生这种情况,由于某种原因,它被优化为始终返回相同的值,而不是重新执行调用。不过好久没看到了。
  • 大家可以关注CMS吗?他很可能是正确的。您需要准确地发布如何将此随机数添加到元素。

标签: javascript jquery math random


【解决方案1】:

随机数函数是一个模拟随机的方程,但它仍然是一个函数。如果你给它相同的种子,第一个答案将是相同的。

您可以尝试更改种子,并在首次加载 javascript 时执行此操作,这样如果随机数生成器有时间组件,则它可以使用加载页面的延迟来更多地随机化数字。

但是,您可能想要更改种子。您可以使用Date() 函数,然后获取毫秒并将其用作种子,这可能有助于首先对其进行加扰。

我认为生成器有一个时间组件,因为它会随着警报而改变,因为这会延迟下一个数字的生成,尽管我还没有对此进行测试。

更新:

我意识到规范声明 Math.random 没有参数,但使用了一个种子。

我是从 C 开始,然后是 Java,所以使用参数没有错误这一事实让我认为它使用了它,但现在我发现这是不正确的。

如果你真的需要种子,最好的办法是编写一个随机数生成器,然后 Knuth 书籍是最好的起点。

【讨论】:

  • 您无法在 Javascript 中更改 Math.random() 的种子。它使用脚本开始执行的当前时间为其播种。
  • @Matt - 我一直只是传入一个值,我没有意识到它被忽略了。
【解决方案2】:

这就是我根据需要解决它的方法。就我而言,它工作得很好,因为我只会偶尔请求数字,而不是按顺序或循环请求。如果您在循环中使用它,这将不起作用,因为它是基于时间的,并且循环将仅以毫秒为间隔执行请求。

function getRandomNumber(quantity_of_nums){
    var milliseconds = new Date().getMilliseconds();
    return Math.floor(milliseconds * quantity_of_nums / 1000);
}

这将为您提供一个从 0 到 quantity_of_nums - 1 的数字

希望对你有帮助!

【讨论】:

  • 1820,1822,1824,1826,1826,1828,1828,1830,1830,1832 似乎不是很随机。 for (i = 0; i < 10; i++) { console.log(getRandomNumber(2000)) }
  • Kevin B. 你说的很对,如果你在循环中使用它是行不通的,因为它是基于时间的,并且循环将在几毫秒内执行请求。更改了文本以澄清这一方面。感谢您的提醒。
  • 这根本不是随机的,日期是一个真正的预测数字。
【解决方案3】:

随机数生成器实际上是伪随机数生成器 - 即它们使用公式来计算实际上是随机的数字流。

因此,对于相同的初始输入值(种子),您将获得相同的流。所以诀窍是用一个好的实际随机种子来播种随机数生成器。

因此,您需要以某种方式将种子传递给 random() - 您可以使用当前时间的某种散列,或您认为具有某种随机性的任何其他数据(如果您希望它“安全随机”——这是一个完全不同的主题,可能在其他地方也有介绍)。

所以使用类似的东西:Math.random(Date.getMilliseconds()) - 可能更接近你想要的。

【讨论】:

  • 嗯,根据 ECMA-262 规范,Math.random() 不带任何参数。你知道Math.random(Date.getMilliseconds())在哪个浏览器上工作吗?
  • @Xavi,你说得对,上面的代码有效,因为传递给Math.random 的参数只是被忽略了......bclary.com/2004/11/07/#a-15.8.2.14
  • 用固定的“种子”测试,IE 和 Firefox 仍然返回随机值。 Xavi 是对的,只是参数被忽略了。
  • (Math.random() + new Date().getMilliseconds() / 1000) / 2 可以被视为“播种”吗?
  • 您正在尝试“为结果添加随机性”,这是一个好主意,但有一个问题:两个随机数的平均值分布不是 i> 统一。用外行的话来说,这意味着,在你的建议中,得到 0.5 的概率大于得到 0.25 的概率。有关更多技术(数学)信息,请参阅:statisticalengineering.com/central_limit_theorem.htm
【解决方案4】:

你可以使用

#include <sys/time.h>

然后要获得范围从 0 到 999,999 的种子,请使用

gettimeofday(&tv, NULL);
srand(tv.tv_usec);

然后,要获取 0 - 499 范围内的随机数,请使用

r = 500*((double)rand() /((double)(RAND_MAX)+(double)(1.0))));

或将此结果加 1 以将其移至 1 - 500 范围内。

祝你好运

【讨论】:

  • Javascript 问题,不是 C/C++。
  • 我当然想知道为什么对这个答案投了反对票。这是对生成所需随机数范围的直接方法的完整描述,之前的答案都没有解决。
  • 因为问题询问如何在 JavaScript 中生成随机数(在编写 jQuery 插件的上下文中),而您的答案解释了如何在 C 或 C++ 中生成随机数。我认为用 C 或 C++ 编写 jQuery 插件是不可能的。很好的答案,只是不适合这个问题。
猜你喜欢
  • 2017-05-29
  • 2015-08-18
  • 2014-04-30
  • 2010-11-06
  • 2011-07-13
  • 2014-05-07
  • 1970-01-01
  • 1970-01-01
  • 2012-12-21
相关资源
最近更新 更多