Why does the following code crash on an iPhone 5 but not an iPhone 5S?

后端 未结 2 1413
谎友^
谎友^ 2020-12-19 03:41
func rand(max: Int?) -> Int {
    var index = Int(arc4random())
    return max? != nil ? (index % max!) : index
}

I get an exception on the last

相关标签:
2条回答
  • 2020-12-19 04:16

    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.

    0 讨论(0)
  • 2020-12-19 04:28

    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.

    0 讨论(0)
提交回复
热议问题