我意识到Swift书籍提供了一个随机数生成器的实现。复制和粘贴这个实现是最佳实践吗?或者有没有这样的库,我们现在就可以使用?
当前回答
使用arc4random_uniform ()
用法:
arc4random_uniform(someNumber: UInt32) -> UInt32
这将为您提供0到someNumber - 1范围内的随机整数。
UInt32的最大值为4,294,967,295(即2^32 - 1)。
例子:
抛硬币 让flip = arc4random_uniform(2) // 0或1 骰子滚 Let roll = arc4random_uniform(6) + 1 // 1 十月的任意一天 Let day = arc4random_uniform(31) + 1 // 1 90年代的任意一年 Let year = 1990 + arc4random_uniform(10)
一般形式:
let number = min + arc4random_uniform(max - min + 1)
其中number、max、min为UInt32。
是什么……
arc4random ()
你也可以通过使用arc4random()得到一个随机数,它会产生一个在0到2^32-1之间的UInt32。因此,要得到一个介于0和x-1之间的随机数,可以将其除以x并取余数。或者换句话说,使用余数运算符(%):
let number = arc4random() % 5 // 0...4
然而,这会产生轻微的模数偏差(参见这里和这里),所以这就是为什么建议使用arc4random_uniform()。
从Int转换到Int
通常情况下,为了在Int和UInt32之间来回转换,这样做是很好的:
let number: Int = 10
let random = Int(arc4random_uniform(UInt32(number)))
但问题是,Int的范围是-2,147,483,648…2,147,483,647在32位系统和范围-9,223,372,036,854,775,808…9223,372,036,854,775,807在64位系统上。将其与0…4,294,967,295的UInt32范围进行比较。U (UInt32)表示无符号。
考虑以下错误:
UInt32(-1) // negative numbers cause integer overflow error
UInt32(4294967296) // numbers greater than 4,294,967,295 cause integer overflow error
所以你只需要确保你的输入参数是在UInt32范围内,你不需要输出是在这个范围之外。
其他回答
var randomNumber = Int(arc4random_uniform(UInt32(5)))
这里5将确保随机数是从0到4生成的。您可以设置相应的值。
@jstn的回答很好,但有点啰嗦。Swift被称为面向协议的语言,因此我们可以通过为协议扩展添加默认实现,而不必为整数族中的每个类实现样板代码来实现相同的结果。
public extension ExpressibleByIntegerLiteral {
public static func arc4random() -> Self {
var r: Self = 0
arc4random_buf(&r, MemoryLayout<Self>.size)
return r
}
}
现在我们可以做:
let i = Int.arc4random()
let j = UInt32.arc4random()
其他的整数类都是可以的。
从iOS 9开始,你可以使用新的GameplayKit类以各种方式生成随机数。
你有四种源类型可以选择:一般随机源(未命名,直到系统选择它做什么),线性同余,ARC4和梅森扭扭。它们可以生成随机int型、浮点型和bool型。
在最简单的层面上,你可以从系统内置的随机源生成一个随机数,如下所示:
GKRandomSource.sharedRandom().nextInt()
这就产生了一个介于- 2147,483,648到2147,483,647之间的数字。如果你想要一个介于0和上界(不包含)之间的数字,你可以使用这个:
GKRandomSource.sharedRandom().nextIntWithUpperBound(6)
GameplayKit内置了一些方便的构造函数来处理骰子。例如,你可以像这样掷一个六面骰子:
let d6 = GKRandomDistribution.d6()
d6.nextInt()
此外,你还可以使用GKShuffledDistribution之类的东西来塑造随机分布。这需要更多解释,但如果你感兴趣,你可以阅读我关于GameplayKit随机数的教程。
斯威夫特4.2
Swift 4.2在标准库中包含了一个原生的、功能相当全的随机数API。(Swift Evolution提案SE-0202)
let intBetween0to9 = Int.random(in: 0...9)
let doubleBetween0to1 = Double.random(in: 0...1)
所有的数字类型都有静态随机数(in:),它接受范围并返回给定范围内的随机数
使用arc4random_uniform ()
用法:
arc4random_uniform(someNumber: UInt32) -> UInt32
这将为您提供0到someNumber - 1范围内的随机整数。
UInt32的最大值为4,294,967,295(即2^32 - 1)。
例子:
抛硬币 让flip = arc4random_uniform(2) // 0或1 骰子滚 Let roll = arc4random_uniform(6) + 1 // 1 十月的任意一天 Let day = arc4random_uniform(31) + 1 // 1 90年代的任意一年 Let year = 1990 + arc4random_uniform(10)
一般形式:
let number = min + arc4random_uniform(max - min + 1)
其中number、max、min为UInt32。
是什么……
arc4random ()
你也可以通过使用arc4random()得到一个随机数,它会产生一个在0到2^32-1之间的UInt32。因此,要得到一个介于0和x-1之间的随机数,可以将其除以x并取余数。或者换句话说,使用余数运算符(%):
let number = arc4random() % 5 // 0...4
然而,这会产生轻微的模数偏差(参见这里和这里),所以这就是为什么建议使用arc4random_uniform()。
从Int转换到Int
通常情况下,为了在Int和UInt32之间来回转换,这样做是很好的:
let number: Int = 10
let random = Int(arc4random_uniform(UInt32(number)))
但问题是,Int的范围是-2,147,483,648…2,147,483,647在32位系统和范围-9,223,372,036,854,775,808…9223,372,036,854,775,807在64位系统上。将其与0…4,294,967,295的UInt32范围进行比较。U (UInt32)表示无符号。
考虑以下错误:
UInt32(-1) // negative numbers cause integer overflow error
UInt32(4294967296) // numbers greater than 4,294,967,295 cause integer overflow error
所以你只需要确保你的输入参数是在UInt32范围内,你不需要输出是在这个范围之外。
推荐文章
- 如何删除默认的导航栏空间在SwiftUI导航视图
- 如何在Ruby中生成a和b之间的随机数?
- 如何在iOS中使用Swift编程segue
- Swift -整数转换为小时/分钟/秒
- 如何舍入一个双到最近的Int在迅速?
- 扁平化数组的数组在Swift
- Swift:声明一个空字典
- java.util.Random真的那么随机吗?我怎么能生成52!(阶乘)可能的序列?
- 从数组中随机选择一个元素
- 在Swift中如何调用GCD主线程上的参数方法?
- swift语言中的结构与类
- 我如何在Swift连接字符串?
- 我应该如何从字符串中删除所有的前导空格?- - - - - -斯威夫特
- 使用该集合的原因。种子功能
- Swift:理解// MARK