代码之家  ›  专栏  ›  技术社区  ›  Andrew Hedges

javascript的math.random有多随机?

  •  108
  • Andrew Hedges  · 技术社区  · 15 年前

    六年来我一直 random number generator 我网站上的页面。很长一段时间以来,这是谷歌在“随机数生成器”上的第一个或第二个结果,并被用来决定几十个(如果不是数百个)论坛和博客上的竞赛和图纸(我知道,因为我在我的网络日志中看到了引用者,通常会去看看)。

    今天有人给我发邮件告诉我 它可能不像我想的那样随机。 她尝试生成非常大的随机数(例如,1到10000000000000000之间),发现它们几乎总是相同的位数。实际上,我将函数包装在一个循环中,这样我就可以生成数千个数字,当然,对于非常大的数字, 变化幅度只有2个数量级。

    为什么?

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

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

    它包括从 Mozilla Developer Network 我从1997年的一些代码中删除了一个不再存在的网页(PaulHoule的“CentralRandomizer1.3”)。查看源代码以查看每个方法的工作方式。

    我读过 here elsewhere 关于 旋转木马。 我感兴趣的是为什么JavaScript内置的结果不会有更大的变化 数学随机 功能。谢谢!

    9 回复  |  直到 6 年前
        1
  •  164
  •   Quentin    15 年前

    给定1到100之间的数字。

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

    给定1到1000之间的数字。

    • 9位有1位
    • 90有两位数
    • 900有3位数
    • 1位有4位数字

    等等。

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

        2
  •  54
  •   jwoolard    15 年前

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

        3
  •  41
  •   Christian    7 年前

    有不同类型的随机性。 Math.random 给你一个统一的数字分布。

    如果你想要不同的数量级,我建议用一个指数函数来创建所谓的 power law distribution :

    function random_powerlaw(mini, maxi) {
        return Math.ceil(Math.exp(Math.random()*(Math.log(maxi)-Math.log(mini)))*mini)
    }
    

    这个函数应该提供与2位数和3位数大致相同的1位数。

    对于随机数也有其他分布,比如 normal distribution (也称为高斯分布)。

        4
  •  18
  •   trlkly Delan Azabani    9 年前

    以下文章解释了主要Web浏览器中的math.random()是如何(非)安全的: "Temporary user tracking in major browsers and Cross-domain information leakage and attacks" by Amid Klein (2008) . 它并不比典型的Java或Windows内置PRNG功能强。

    另一方面,实现周期2^19937-1的sfmt需要为每个prng序列维护2496字节的内部状态。有些人可能认为这是不可原谅的代价。

        5
  •  17
  •   Arafangion    6 年前

    我觉得很随意! (提示:这取决于浏览器。)

    就我个人而言,我认为我的实现会更好,尽管我从 XKCD ,应始终确认谁:

    function random() {
      return 4; // Chosen by a fair dice throw. Guaranteed to be random.
    }
    
        6
  •  5
  •   Greg    15 年前

    如果使用10000000000000000这样的数字,则会超出JavaScript使用的数据类型的准确性。注意,所有生成的数字都以“00”结尾。

        7
  •  5
  •   zie1ony    12 年前

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

    我的 Sierpiński triangle 说这很随意: Fractal

        8
  •  3
  •   Joey Gumbo    15 年前

    好吧,如果你生成的数字达到,比如说,1e6,你很有希望得到所有概率近似相等的数字。这也意味着你只有十分之一的机会得到一个少于一位数的数字。百分之一的概率会减少两位数,等等。我怀疑你在使用另一个RNG时会看到很大的不同,因为你在数字上有一个均匀的分布,而不是它们的对数。

        9
  •  0
  •   ttw    7 年前

    从1到n均匀分布的非随机数具有相同的性质。注意(在某种意义上)这是一个精确的问题。在0-99上的均匀分布(作为整数)有90%的数字有两位数。在0-999999上的均匀分布有905个数字,其中5个数字。

    任何一组数字(在一些不太严格的条件下)都有密度。当有人想讨论“随机”数字时,应该指定这些数字的密度(如上所述)。常见的密度是均匀密度。还有其他一些:指数密度、法向密度等。在提出随机数生成器之前,必须选择与之相关的密度。而且,来自一个密度的数字通常可以通过龋齿的方式很容易地转换成另一个密度。