Swift:64 位整数的随机数? [英] Swift: Random number for 64-bit integers?

查看:24
本文介绍了Swift:64 位整数的随机数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,在我当前的项目中,我需要处理 64 位整数,并且需要在高达 1000 亿的范围内抓取随机数.arc4random()/arc4random_uniform() 仅适用于无符号 32 位整数.

So, with my current project, I need to work with 64-bit integers and I need to grab random numbers between ranges up to 100 billion. arc4random()/arc4random_uniform() only works with unsigned 32-bit integers.

我可能有点捏造它,因为我每次调用的最小/最大范围可能不会超过 20 亿,但我想在未来证明自己,以防万一我决定,好吧,我确实需要更大的范围.

I can probably fudge it a little because my min/max range for every call will likely not exceed 2 billion, but I'd like to futureproof myself in case I decide that, well, I do need a broader range.

有什么建议吗?

推荐答案

更新:Swift 4.2(随 Xcode 10.1 分发)开始,在Swift 标准库,见

Update: As of Swift 4.2 (distributed with Xcode 10.1) there is a unified random API in the Swift standard library, see

你可以简单地调用

UInt64.random(in: minValue ... maxValue)

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

to get a random number in the given range.

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

(Previous answer for Swift < 4.2:) With arc4random_buf() you can create "arbitrary large" random numbers, so this would be a possible solution:

// 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
}

当上限不是 2 的幂时,此方法会遇到模偏差"问题(参见 为什么人们说使用随机数生成器时存在模偏差?).我在这里翻译了答案https://stackoverflow.com/a/10989061/1187415从上面的线程到Swift:

This method suffers from the "modulo bias" problem when the upper bound is not a power of 2 (See Why do people say there is modulo bias when using a random number generator?). Here I have translated the answer https://stackoverflow.com/a/10989061/1187415 from above thread to 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
}

(乍一看好像循环可能不会终止,但它可以显示平均需要少于 2 次迭代.)

(At first sight it looks as if the loop might not terminate, but it can be shown that on average less than 2 iterations are needed.)

这篇关于Swift:64 位整数的随机数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆