В Swift
арифметические операторы по умолчанию не переполняются или не становятся недостаточными, как в других языках программирования, т. Е. C
, Java
Это означает, что если вы попытаетесь вставить число в целочисленную константу или переменную, которая не может содержать это значение, по умолчанию Swift сообщает об ошибке, а не позволяет создать недопустимое значение.
Такое поведение обеспечивает дополнительную безопасность при работе с слишком большими или слишком маленькими числами.
Пример 1 (по умолчанию): переполнение / недостаточное заполнение игнорируется
Целочисленный тип Int16
может содержать числа от -32768
до 32767
. Попытка установить для переменной Int16
число вне этого диапазона вызывает ошибку:
var potentialOverflow:Int16 = Int16.max // potentialOverflow equals 32767, which is the maximum value an Int16 can hold potentialOverflow += 1 // this causes an error
Однако, если вы специально хотите, чтобы условие переполнения сокращало количество доступных битов, вы можете выбрать это поведение, а не запускать ошибку.
Swift предоставляет три оператора арифметического переполнения, которые выбирают поведение переполнения для целочисленных вычислений. Все эти операторы начинаются с амперсанда (&
):
- Добавление переполнения (
&+
) - Вычитание переполнения (
&-
) - Умножение переполнения (
&*
)
Пример 2: условие переполнения (положительное направление)
Числа могут переполняться как в положительном, так и в отрицательном направлении.
Вот пример того, что происходит, когда беззнаковое целое число может переполняться в положительном направлении с помощью оператора сложения переполнения (&+
):
var signedOverflow:Int16 = Int16.max // signedOverflow equals 32767, which is the maximum value an Int16 can hold signedOverflow &+= 1 // this wil print -32768, which is min value of Int16
Пример 3. Переполнение в отрицательном направлении (недополнение)
Нечто подобное происходит, когда беззнаковое целое число может переполняться в отрицательном направлении. Вот пример использования оператора вычитания переполнения (&-
):
var signedOverflow:Int16 = Int16.min // signedOverflow equals -32768, which is the minimum value an Int16 can hold signedOverflow &-= 1 // this wil print 32767, which is max value of Int16
Как для знаковых, так и для беззнаковых целых чисел, переполнение в положительном направлении переходит от максимального допустимого целочисленного значения к минимуму, а переполнение в отрицательном направлении переходит от минимального значения к максимальному.
Итак, теперь вопрос в том, почему арифметическое переполнение игнорируется в Swift?
На то есть три причины:
- Стоимость проверки переполнения (для каждой отдельной арифметической операции) во время выполнения является чрезмерной.
- Сложность доказательства того, что проверка переполнения может быть опущена во время компиляции, чрезмерна.
- В некоторых случаях (например, вычисления CRC, библиотеки с большими числами и т. Д.) «Перенос при переполнении» более удобен для программистов.
Вопросы?
Не стесняйтесь оставлять комментарии ниже, если у вас есть вопросы.
Если вам понравилась эта статья, не стесняйтесь поделиться ею с друзьями и оставить мне комментарий. Кроме того, нажмите кнопку 👏 хлопка ниже, чтобы показать, насколько вам нравится статья.
Спасибо за чтение! 👨🏼💻 Следите за моей следующей статьей.
Вы можете найти меня на:
Твиттер | LinkedIn | GitHub | Средний | HackerRank | LeetCode | "Переполнение стека"