JavaScript的Math.random有多随机?

2022-08-30 04:44:08

6年来,我在我的网站上有一个随机数生成器页面。很长一段时间以来,这是Google上“随机数生成器”的第一个或第二个结果,并且已经用于在讨论论坛和博客上决定数十个甚至数百个竞赛和绘图(我知道,因为我在我的网络日志中看到引用者,通常会去看一看)。

今天,有人给我发了电子邮件,告诉我它可能不像我想象的那么随机。她尝试生成非常大的随机数(例如,在1到10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000事实上,我将函数包装在一个循环中,这样我就可以生成数千个数字,果然,对于非常大的数字,变化只有大约2个数量级。

为什么?

这是循环版本,因此您可以亲自尝试一下:

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

它既包括从Mozilla Developer Network获取的直接实现,也包括我从不再存在的网页上滑动的1997年的一些代码(Paul Houle的“Central Randomizer 1.3”)。查看源代码以查看每种方法的工作原理。

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


答案 1

给定介于 1 和 100 之间的数字。

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

给定介于 1 和 1000 之间的数字。

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

等等。

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


答案 2

您的结果实际上是意料之中的。如果随机数均匀分布在 1 到 10^n 的范围内,则预计大约 9/10 的数字具有 n 位数字,另外 9/100 的数字具有 n-1 位数字。