Swift:64 位整数的随机数? [英] Swift: Random number for 64-bit integers?
问题描述
因此,在我当前的项目中,我需要处理 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屋!