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

查看:434
本文介绍了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 (目前处于测试阶段)有一个统一的随机Swift标准库中的API,参见

Update: As of Swift 4.2 (currently in beta) there is a unified random API in the Swift standard library, see

  • SE 0202 Random Unification.

使用最近的Swift 4.2开发人员快照,您只需调用

With a recent Swift 4.2 developer snapshot you can simply call

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

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

to get a random number in the given range.

(上一个答案f或斯威夫特< 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天全站免登陆