Swift:64位整数的随机数?

RH2*_*224 12 random arc4random ios swift xcode6

因此,在我目前的项目中,我需要使用64位整数,我需要在范围高达1000亿之间获取随机数.arc4random()/ arc4random_uniform()仅适用于无符号32位整数.

我可能会稍微捏一下,因为我的每次通话的最小/最大范围可能不会超过20亿,但我想在未来的情况下保护自己,以防我决定,我确实需要更广泛的范围.

有什么建议?

Mar*_*n R 25

更新:Swift 4.2(与Xcode 10.1一起发布)开始,Swift标准库中有一个统一的随机API,请参阅

你可以简单地打电话

UInt64.random(in: minValue ... maxValue)
Run Code Online (Sandbox Code Playgroud)

获取给定范围内的随机数.


(Swift <4.2 :)的上一个答案随着arc4random_buf()你可以创建"任意大"的随机数,所以这将是一个可能的解决方案:

// Swift 2:
func random64(upper_bound: UInt64) -> UInt64 {

    // Generate 64-bit random number:
    var rnd : UInt64 = 0
    arc4random_buf(&rnd, sizeofValue(rnd))

    return rnd % upper_bound
}

// Swift 3:
func random64(upper_bound: UInt64) -> UInt64 {

    // Generate 64-bit random number:
    var rnd : UInt64 = 0
    arc4random_buf(&rnd, MemoryLayout.size(ofValue: rnd))

    return rnd % upper_bound
}
Run Code Online (Sandbox Code Playgroud)

当上限不是2的幂时,这种方法会遇到"模偏"问题(参见为什么人们说使用随机数发生器时存在模偏差?).在这里,我已将上述帖子的答案/sf/answers/769234301/翻译 成Swift:

// Swift 2:
func random64(upper_bound: UInt64) -> UInt64 {

    // Generate 64-bit random value in a range that is
    // divisible by upper_bound:
    let range = UInt64.max - UInt64.max % upper_bound
    var rnd : UInt64 = 0
    repeat {
        arc4random_buf(&rnd, sizeofValue(rnd))
    } while rnd >= range

    return rnd % upper_bound
}

// Swift 3:
func random64(upper_bound: UInt64) -> UInt64 {

    // Generate 64-bit random value in a range that is
    // divisible by upper_bound:
    let range = UInt64.max - UInt64.max % upper_bound
    var rnd : UInt64 = 0
    repeat {
        arc4random_buf(&rnd, MemoryLayout.size(ofValue: rnd))
    } while rnd >= range

    return rnd % upper_bound
}
Run Code Online (Sandbox Code Playgroud)

(乍一看,它看起来好像循环可能没有终止,但可以证明平均需要少于2次迭代.)


Kir*_*ins 17

也许你可以把它组成32位整数:

var random64 = Int64(arc4random()) + (Int64(arc4random()) << 32)
Run Code Online (Sandbox Code Playgroud)