func rand(max: Int?) -> Int {
var index = Int(arc4random())
return max? != nil ? (index % max!) : index
}
我在最后一行得到例外:EXC_BAD_INSTRUCTION
我猜这与iPhone 5S是64位而5不是这样的事实有关,但我在上面的函数中没有看到任何涉及64位的内容?
我能够通过以下调整解决问题,但我仍然无法解释原因。
func rand(max: Int?) -> Int {
var index = arc4random()
return max? != nil ? Int(index % UInt32(max!)) : Int(index)
}
答案 0 :(得分:15)
Int
整数类型是iPhone 5上的32位整数和5S上的64位整数。由于arc4random()
会返回一个UInt32
,其在iPhone 5上的正值范围是Int
的两倍,因此您的第一个版本基本上有50%的可能性在这一行上崩溃:
var index = Int(arc4random())
您的修改后的版本等待转换,直到您使用max
的模数求和,因此可以安全地转换为Int
。你应该看看arc4random_uniform,它为你处理模数,并避免你当前实现中固有的偏见。
答案 1 :(得分:6)
看起来你发现了,arc4random返回一个无符号的32位整数。所以0到4,294,967,295。此外,Int的大小也不同,具体取决于运行它的系统。
On a 32-bit platform, Int is the same size as Int32. On a 64-bit platform, Int is the same size as Int64.
在iPhone 5上,Int只会持有-2,147,483,648到+2,147,483,647。在iPhone 5S上,Int可以持有-9,223,372,036,854,775,808至+9,223,372,036,854,775,807。无符号32位整数可以溢出Int32但不会溢出Int64。
More information关于使用什么随机函数以及为什么。