JavaScript的Math.random是多么随机?

And*_*ges 111 javascript random

6年来,我的网站上有一个随机数生成器页面.很长一段时间,它是Google上"随机数生成器"的第一个或第二个结果,并且已被用于在论坛和博客上决定数十个(如果不是数百个)竞赛和绘图(我知道因为我看到了我的推荐人)网络日志,通常去看看).

今天,有人通过电子邮件告诉我,它可能不像我想的那么随机.她尝试生成非常大的随机数(例如,介于1和10000000000000000000之间),发现它们几乎总是相同的位数.实际上,我将函数包装在一个循环中,因此我可以生成数千个数字,当然,对于非常大的数字,变化只有大约2个数量级.

为什么?

这是循环版本,所以你可以自己试试:

http://andrew.hedges.name/experiments/random/randomness.html

它既包括Mozilla开发者网络的直接实现,也包括1997年我从不再存在的网页中删除的一些代码(Paul Houle的"Central Randomizer 1.3").查看源以查看每种方法的工作原理.

我在这里其他地方读过有关Mersenne Twister的文章.我感兴趣的是为什么JavaScript的内置Math.random函数的结果没有更大的变化.谢谢!

Que*_*tin 177

给定1到100之间的数字.

  • 9有1位数(1-9)
  • 90有2位数(10-99)
  • 1有3位数(100)

给定1到1000之间的数字.

  • 9有1位数
  • 90有2位数
  • 900有3位数
  • 1有4位数

等等.

因此,如果您随机选择一些,那么绝大多数所选数字将具有相同的位数,因为绝大多数可能的值具有相同的位数.

  • @ R.Pate - 随机数*生成*没有多大用处,除非它是长期均匀分布的 (17认同)
  • 你对随机性的意义完美而均匀地分布是有趣的... (11认同)
  • 再读一遍.@David只说明限制之间有哪种数字,而不是选择N个随机数的结果.我承认这个标题是误导性的. (3认同)
  • 为了记录,我投了这个和@jwoolard的答案.我选择这一个作为公认的答案,因为这些例子清楚地说明为什么数字的分布偏向于具有更多数字的数字. (3认同)

jwo*_*ard 55

您的结果实际上是预期的.如果随机数均匀分布在1到10 ^ n的范围内,那么您可能希望大约9/10的数字具有n个数字,并且另外9/100的数字具有n-1个数字.

  • 究竟.预计数字位数的分布将会出现偏差.然而,数字的对数的分布是均匀的. (8认同)

Chr*_*ian 44

有不同类型的随机性.Math.random为您提供统一的数字分布.

如果你想要不同的数量级,我建议使用指数函数来创建所谓的幂律分布:

function random_powerlaw(mini, maxi) {
    return Math.ceil(Math.exp(Math.random()*(Math.log(maxi)-Math.log(mini)))*mini)
}
Run Code Online (Sandbox Code Playgroud)

此功能应该为您提供与2位数字和3位数字大致相同的1位数字.

随机数也有其他分布,如正态分布(也称为高斯分布).


Ara*_*ion 18

看起来完全随机给我!(提示:这取决于浏览器.)

就我个人而言,我认为我的实施会更好,尽管我从XKCD中偷走了它,而XKCD应该始终得到承认:

function random() {
  return 4; // Chosen by a fair dice throw. Guaranteed to be random.
}
Run Code Online (Sandbox Code Playgroud)

  • +1表示它依赖浏览器,-1表示没有链接借用xkcd. (17认同)
  • OT:我很惊讶和高兴“ XKCD”是本周大学挑战问题的答案:D (2认同)
  • Bergi:直接链接还不够? (2认同)

jj1*_*bdx 18

下面的文章解释了主要Web浏览器中的math.random()是如何(不)安全的: "主要浏览器中的临时用户跟踪以及跨域信息泄漏和攻击",Amid Klein(2008).它并不比典型的Java或Windows内置PRNG功能更强大.

另一方面,实现时段2 ^ 19937-1的SFMT需要为每个PRNG序列维持2496字节的内部状态.有些人可能认为这是不可原谅的代价.

  • +1:提到的论文很棒,远远超出了最初问题的内容。 (2认同)

Gre*_*reg 5

如果您使用10000000000000000000之类的数字,那么您将超出Javascript使用的数据类型的准确性.请注意,生成的所有数字都以"00"结尾.

  • @Johannes - 这是*他的问题之一:) (3认同)

zie*_*ony 5

我在Chaos Game上尝试了JS伪随机数生成器.

我的Sierpiński三角形说它非常随意: 分形

  • 链接死了 - 也许是Github回购? (4认同)
  • 您是否介意在这里分享三角形代码和jsfiddle/jsbin,以便我们可以在实践中轻松地查看不同的浏览器? (2认同)
  • usp :( work, work, work 链接:http://kubaplas.vot.pl/green/fractal/ 第一个参数是顶点的 nr。第二个参数是线段的交点(从 0 到 1)。就这样实验。 (2认同)