Почему следующий код разбился на iPhone 5, но не на iPhone 5S?
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)
}
Ответы
Ответ 1
Integer тип Int
- это 32-разрядное целое число на iPhone 5 и 64-разрядное целое число на 5S. Поскольку arc4random()
возвращает a UInt32
, который имеет двойной положительный диапазон Int
на iPhone 5, ваша первая версия в основном имеет 50% -ный шанс сбой в этой строке:
var index = Int(arc4random())
Ваша измененная версия ждет конвертировать до тех пор, пока вы не возьмете сумму по модулю с помощью max
, поэтому ее можно конвертировать в Int
. Вы должны проверить arc4random_uniform, который обрабатывает модуль для вас и избегает некоторого смещения, присущего вашей текущей реализации.
Ответ 2
Как вам кажется, вы обнаружили, что 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.
Дополнительная информация о том, какую функцию использовать и почему.