在 Swift, Obj-C 中使用 Arc4Random() 的擲骰偏差

Marvin Lin
3 min readJun 17, 2018

--

你常用的骰子有幾面?

在前一篇文章,我做了 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) 吧

參考資料:

--

--

Marvin Lin

突然有天對程式開始產生興趣,先從 Python 開始,然後轉入 Swift 。因為這個世界很有趣,所以我會不斷的推展我所接觸的領域。