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 (目前处于测试阶段)有一个统一的随机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屋!