簡體   English   中英

JavaScript的Math.random是多么隨機?

[英]How random is JavaScript's Math.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函數的結果沒有更大的變化。 謝謝!

給定1到100之間的數字。

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

給定1到1000之間的數字。

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

等等。

因此,如果您隨機選擇一些,那么絕大多數所選數字將具有相同的位數,因為絕大多數可能的值具有相同的位數。

您的結果實際上是預期的。 如果隨機數均勻分布在1到10 ^ n的范圍內,那么您可能希望大約9/10的數字具有n個數字,並且另外9/100的數字具有n-1個數字。

有不同類型的隨機性。 Math.random為您提供統一的數字分布。

如果你想要不同的數量級,我建議使用指數函數來創建所謂的冪律分布

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

此功能應該為您提供與2位數字和3位數字大致相同的1位數字。

隨機數也有其他分布,如正態分布 (也稱為高斯分布)。

看起來完全隨機給我! (提示:這取決於瀏覽器。)

就我個人而言,我認為我的實施會更好,盡管我從XKCD中偷走了它,應該始終承認:

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

下面的文章解釋了主要Web瀏覽器中的math.random()是如何(不)安全的: “主要瀏覽器中的臨時用戶跟蹤以及跨域信息泄漏和攻擊”,Amid Klein(2008) 它並不比典型的Java或Windows內置PRNG功能更強大。

另一方面,實現時段2 ^ 19937-1的SFMT需要為每個PRNG序列維持2496字節的內部狀態。 有些人可能認為這是不可原諒的代價。

如果您使用10000000000000000000之類的數字,那么您將超出Javascript使用的數據類型的准確性。 請注意,生成的所有數字都以“00”結尾。

我在Chaos Game上嘗試了JS偽隨機數生成器。

我的Sierpiński三角形說它非常隨意: 分形

好吧,如果您生成的數字高達1e6,那么您希望所有數字的概率大致相等。 這也意味着你只有十分之一的機會得到一個數字少一個數字。 百分之一的機會減少兩位數等等。我懷疑你在使用另一個RNG時會看到很多不同,因為你在數字上有一個統一的分布,而不是它們的對數。

從1到N均勻分布的非隨機數具有相同的屬性。 請注意(在某種意義上)這是一個精確的問題。 0-99(作為整數)的均勻分布確實有90%的數字具有兩位數。 在0-999999上的均勻分布有905個數字有五位數。

任何一組數字(在一些不太嚴格的條件下)都有密度。 當有人想討論“隨機”數字時,應指定這些數字的密度(如上所述)。常見密度是均勻密度。 還有其他:指數密度,正常密度等。在提出隨機數發生器之前,必須選擇哪個密度是相關的。 而且,來自一個密度的數字通常可以通過齲齒方式容易地轉換為另一個密度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM