func rand(max: Int?) -> Int {
var index = Int(arc4random())
return max? != nil ? (index % max!) : index
}
I get an exception on the last line: EXC_BAD_INSTRUCTION
I'm guessing it has something to do with the fact that the iPhone 5S is 64 bit while the 5 is not, but I don't see anything in the function above that deals with 64 bits?
I was able to resolve the issue with the following adjustments, but I still cannot explain why.
func rand(max: Int?) -> Int {
var index = arc4random()
return max? != nil ? Int(index % UInt32(max!)) : Int(index)
}
The Int
integer type is a 32-bit integer on the iPhone 5 and a 64-bit integer on the 5S. Since arc4random()
returns a UInt32
, which has twice the positive range of an Int
on the iPhone 5, your first version basically has a 50% chance of crashing on this line:
var index = Int(arc4random())
Your modified version waits to convert until you take the modulo sum with max
, so it's safe to convert to Int
there. You should check out arc4random_uniform, which handles the modulo for you and avoids some bias inherent in your current implementation.
As it seems like you found out, arc4random returns an unsigned 32 bit integer. So 0 to 4,294,967,295. Also, Int is a different size depending on the system that it is running on.
From "Swift reference:"
On a 32-bit platform, Int is the same size as Int32. On a 64-bit platform, Int is the same size as Int64.
On an iPhone 5, Int will only hold −2,147,483,648 to +2,147,483,647. On an iPhone 5S, Int can hold −9,223,372,036,854,775,808 to +9,223,372,036,854,775,807. An unsigned 32 bit integer can overflow a Int32 but never a Int64.
More information on what random function to use and why.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With