在 Swift, Obj-C 中使用 Arc4Random() 的擲骰偏差
在前一篇文章,我做了 6 億次擲骰,也做了 600回每回60萬次的擲骰。但我仍然覺得我沒有真正的碰到 arc4Random 的核心。在經過強者我朋友的指導後,這篇就是我對 arc4Random() 的理解。歡迎各界給點指教
↓如果對 6 億次擲骰結果有興趣的,可以看這一篇。
如果你在 arc4Random() 上按了查詢,你會看到下面這樣的圖示。
表示這個函數會返回 UInt32,而這個 UInt 32 就表示他的值是有「範圍」的。所以他的值一定落在 0 ~ 2 ^ 32 - 1。(總數是 2 的 32 次方,但是從 0 開始算)
而這樣的範圍,如果他如果可以整除 6 ,那就表示他骰子每面出現的機率會一樣,如果不行,那就表示一定有幾個面的機率會比較高。
好!計算開始
2 ^ 32 次方是 4,294,967,296 這個數字。
這個數字除以 6 ,商數為715,827,882 ,餘數為4。
這就直接說明了你的 arc4Random() % 6 + 1 的結果, 1 ~ 4 的數字會多 5, 6 一點點。
如果要說的詳細一點,就是
1 ~ 4 的骰面出現的機率是 715,827,883 / 4,294,967,296
5 , 6 的骰面出現的機率是 715,827,882 / 4,294,967,296
所以 5 和 6 的機率會比其他面的機率少 0.000000000232831 左右。
如果你希望使用 arc4Random() 函數,但又希望你出來的骰子每面機率要一樣,你就要使用 arc4Random_uniform() 這個函數。
再以六面骰為例
let diceRoll = Int(arc4Random_uniform(5) + 1)
這樣,你就可以確保你的每個骰面出現的機率一樣了。
或者,在 Swift4.2 以後,就直接用 Int.random(in: 1...6) 吧
參考資料: