Swift 如何在Apple';什么是快速的语言?
我意识到Swift手册提供了一个随机数生成器的实现。将此实现复制并粘贴到自己的程序中是最佳做法吗?或者有一个库可以这样做,我们现在可以使用吗?我已经能够使用Swift 如何在Apple';什么是快速的语言?,swift,random,Swift,Random,我意识到Swift手册提供了一个随机数生成器的实现。将此实现复制并粘贴到自己的程序中是最佳做法吗?或者有一个库可以这样做,我们现在可以使用吗?我已经能够使用rand()来获得一个随机的CInt。您可以使用如下方法将其设置为Int: let myVar: Int = Int(rand()) 您可以使用您最喜欢的C随机函数,如果需要,只需将value转换为Int即可。您可以使用与C相同的方法: let randomNumber = arc4random() randomNumber被推断为类型U
rand()
来获得一个随机的CInt。您可以使用如下方法将其设置为Int:
let myVar: Int = Int(rand())
您可以使用您最喜欢的C随机函数,如果需要,只需将value转换为Int即可。您可以使用与C相同的方法:
let randomNumber = arc4random()
randomNumber
被推断为类型UInt32
(32位无符号整数)Swift 4.2+
Xcode 10附带的Swift 4.2为许多数据类型引入了新的易于使用的随机函数。
可以对数值类型调用random()
方法
let randomInt = Int.random(in: 0..<6)
let randomDouble = Double.random(in: 2.71828...3.14159)
let randomBool = Bool.random()
让randomInt=Int.random(in:0..使用arc4random_uniform(n)
表示0到n-1之间的随机整数
let diceRoll = Int(arc4random_uniform(6) + 1)
将结果强制转换为Int,这样您就不必显式地将VAR键入为UInt32
(这似乎不快速)。为Swift 4.2编辑
从Swift 4.2开始,不再使用导入的C函数arc4random_uniform(),现在可以使用Swift自己的本机函数
// Generates integers starting with 0 up to, and including, 10
Int.random(in: 0 ... 10)
您可以使用random(in:)
为其他基本值获取随机值;例如Int、Double、Float甚至Bool
Swift版本<4.2
此方法将生成给定最小值和最大值之间的随机Int
值
func randomInt(min: Int, max: Int) -> Int {
return min + Int(arc4random_uniform(UInt32(max - min + 1)))
}
编辑:
arc4random
在Swift中运行良好,但基本函数仅限于32位整数类型(Int
在iPhone 5S和现代Mac上为64位)。以下是一个通用函数,用于表示可由整数文本表示的类型的随机数:
public func arc4random<T: ExpressibleByIntegerLiteral>(_ type: T.Type) -> T {
var r: T = 0
arc4random_buf(&r, MemoryLayout<T>.size)
return r
}
有了它,我们可以为相同的参数扩展Int64
,处理溢出:
public extension Int64 {
public static func random(lower: Int64 = min, upper: Int64 = max) -> Int64 {
let (s, overflow) = Int64.subtractWithOverflow(upper, lower)
let u = overflow ? UInt64.max - UInt64(~s) : UInt64(s)
let r = UInt64.random(upper: u)
if r > UInt64(Int64.max) {
return Int64(r - (UInt64(~lower) + 1))
} else {
return Int64(r) + lower
}
}
}
为了完成这个家庭
private let _wordSize = __WORDSIZE
public extension UInt32 {
public static func random(lower: UInt32 = min, upper: UInt32 = max) -> UInt32 {
return arc4random_uniform(upper - lower) + lower
}
}
public extension Int32 {
public static func random(lower: Int32 = min, upper: Int32 = max) -> Int32 {
let r = arc4random_uniform(UInt32(Int64(upper) - Int64(lower)))
return Int32(Int64(r) + Int64(lower))
}
}
public extension UInt {
public static func random(lower: UInt = min, upper: UInt = max) -> UInt {
switch (_wordSize) {
case 32: return UInt(UInt32.random(UInt32(lower), upper: UInt32(upper)))
case 64: return UInt(UInt64.random(UInt64(lower), upper: UInt64(upper)))
default: return lower
}
}
}
public extension Int {
public static func random(lower: Int = min, upper: Int = max) -> Int {
switch (_wordSize) {
case 32: return Int(Int32.random(Int32(lower), upper: Int32(upper)))
case 64: return Int(Int64.random(Int64(lower), upper: Int64(upper)))
default: return lower
}
}
}
在所有这些之后,我们终于可以这样做:
let diceRoll = UInt64.random(lower: 1, upper: 7)
var fibs = ArraySlice([1, 1])
var fibGenerator = GeneratorOf{
_ -> Int? in
fibs.append(fibs.reduce(0, combine:+))
return fibs.removeAtIndex(0)
}
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
GKRandomSource.sharedRandom().nextInt()
let d6 = GKRandomDistribution.d6()
d6.nextInt()
print(UInt8.random)
我使用了以下代码:
var k: Int = random() % 10;
此处5将确保通过0到4生成随机数。您可以相应地设置值。您可以像这样使用GeneratorOf
:
let diceRoll = UInt64.random(lower: 1, upper: 7)
var fibs = ArraySlice([1, 1])
var fibGenerator = GeneratorOf{
_ -> Int? in
fibs.append(fibs.reduce(0, combine:+))
return fibs.removeAtIndex(0)
}
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
GKRandomSource.sharedRandom().nextInt()
let d6 = GKRandomDistribution.d6()
d6.nextInt()
print(UInt8.random)
我想补充现有答案,Swift书中的随机数生成器示例是线性同余生成器(LCG),这是一个非常有限的例子,不应该被排除在少数几个小例子之外,在这些例子中,随机性的质量根本不重要。LCG不应该用于加密目的
arc4random()
要好得多,可以用于大多数目的,但同样不应用于加密目的。
如果你想保证加密的东西,请使用<代码> ScCopyRyByType()/<代码>注意,如果你将一个随机数生成器构建成某个东西,其他人可能会终止(MIS)-使用它作为密码目的(例如密码、密钥或盐生成),那么你应该考虑使用<代码> ScCopReavyByt()
无论如何,即使您的需求不太需要。从iOS 9开始,您可以使用新的GameplayKit类以多种方式生成随机数
您有四种源类型可供选择:普通随机源(未命名,由系统选择其功能)、线性全等、ARC4和Mersenne Twister。它们可以生成随机整数、浮点和布尔
在最简单的级别上,您可以从系统的内置随机源生成一个随机数,如下所示:
let diceRoll = UInt64.random(lower: 1, upper: 7)
var fibs = ArraySlice([1, 1])
var fibGenerator = GeneratorOf{
_ -> Int? in
fibs.append(fibs.reduce(0, combine:+))
return fibs.removeAtIndex(0)
}
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
GKRandomSource.sharedRandom().nextInt()
let d6 = GKRandomDistribution.d6()
d6.nextInt()
print(UInt8.random)
这将生成一个介于-2147483648和2147483647之间的数字。如果您想要一个介于0和上限(独占)之间的数字,请使用以下选项:
GKRandomSource.sharedRandom().nextIntWithUpperBound(6)
GameplayKit内置了一些方便的构造器来处理骰子。例如,您可以像这样滚动六面骰子:
let diceRoll = UInt64.random(lower: 1, upper: 7)
var fibs = ArraySlice([1, 1])
var fibGenerator = GeneratorOf{
_ -> Int? in
fibs.append(fibs.reduce(0, combine:+))
return fibs.removeAtIndex(0)
}
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
GKRandomSource.sharedRandom().nextInt()
let d6 = GKRandomDistribution.d6()
d6.nextInt()
print(UInt8.random)
此外,您还可以使用GKShuffledDistribution之类的工具来塑造随机分布。这需要更多的解释,但如果您感兴趣,您可以。使用arc4random\u uniform()
用法:
let number = min + arc4random_uniform(max - min + 1)
arc4random\u统一(某些数字:UInt32)->UInt32
这将为您提供范围0
到someNumber-1
的随机整数
UInt32
的最大值为4294967295(即2^32-1
)
示例:
let number = min + arc4random_uniform(max - min + 1)
- 投币
let flip = arc4random_uniform(2) // 0 or 1
- 骰子卷
let roll = arc4random_uniform(6) + 1 // 1...6
- 十月的随机日
let day = arc4random_uniform(31) + 1 // 1...31
- 1990年代的随机年份
let year = 1990 + arc4random_uniform(10)
let number = min + arc4random_uniform(max - min + 1)
其中,number
、max
和min
是UInt32
let generator = Int(arc4random_uniform(10))
print(generator)
那么...怎么样
arc4random()
您还可以使用arc4random()
获得一个随机数,该随机数产生一个介于0和2^32-1之间的UInt32
。因此,要获得介于0
和x-1
之间的随机数,您可以将其除以x
,然后取余数。或者换句话说,使用:
但是,这会产生轻微的影响(另请参见和),因此建议使用arc4random\u uniform()
与Int的转换
通常,这样做可以在Int
和UInt32
之间来回转换:
let number: Int = 10
let random = Int(arc4random_uniform(UInt32(number)))
但问题是,在32位系统上的范围是-2147483648…2147483647
,而在64位系统上的范围是-9223372036854775808…9223372036854775807
。将其与UInt32
范围0…4294967295
进行比较。UInt32
的U
表示无符号
考虑以下错误:
UInt32(-1) // negative numbers cause integer overflow error
UInt32(4294967296) // numbers greater than 4,294,967,295 cause integer overflow error
因此,您只需确保输入参数在UInt32
范围内,并且不需要输出为ou
let randInt = Int.random(in: 1..<10)
let randFloat = Float.random(in: 1..<20)
let randDouble = Double.random(in: 1...30)
let randCGFloat = CGFloat.random(in: 1...40)
let randomIntFrom0To10 = Int.random(in: 0 ..< 10)
let randomDouble = Double.random(in: 1 ... 10)
let intBetween0to9 = Int.random(in: 0...9)
let doubleBetween0to1 = Double.random(in: 0...1)
let numbers: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
import GameKit
private func randomNumberGenerator() -> Int {
let random = GKRandomSource.sharedRandom().nextInt(upperBound: numbers.count)
return numbers[random]
}
randomNumberGenerator()
let randomNumber = numbers.randomElement()!
print(randomNumber)
let generator = Int(arc4random_uniform(10))
print(generator)
let iterator: Int = (1...10).makeIterator().shuffled().first!
print(iterator)
let randomizer = Int.random(in: 1...10)
print(randomizer)
// 1
let digit = Int.random(in: 0..<10)
// 2
if let anotherDigit = (0..<10).randomElement() {
print(anotherDigit)
} else {
print("Empty range.")
}
// 3
let double = Double.random(in: 0..<1)
let float = Float.random(in: 0..<1)
let cgFloat = CGFloat.random(in: 0..<1)
let bool = Bool.random()