Арифметика
Чему вы научитесь:
- предсказывать результат деления и остатка целых чисел, в том числе отрицательных;
- объяснять, что происходит, когда число не помещается в свой тип, и зачем нужен
&+; - сравнивать значения и объединять условия через
&&,||и!; - проверять, попадает ли число в диапазон, и выбирать одно из двух значений оператором
? :.

Swift считает, как калькулятор, но у этого калькулятора свои правила. Он помнит тип каждого числа, целое оно или дробное, и от типа зависит ответ.
Сложение, вычитание и умножение целых чисел работают так же, как в школе. С делением иначе. Представьте, что вы делите 17 конфет между пятью детьми. Резать конфеты нельзя: каждый получает целое число конфет, а лишние остаются у вас. Так Swift и делит целые числа:
let sweets = 17
let kids = 5
print(sweets / kids) // 3
print(sweets % kids) // 2Давайте посмотрим, что напечатала программа:
sweets / kidsпечатает3: семнадцать конфет на пятерых — по три каждому.sweets % kidsпечатает2: две конфеты остаются у вас.
Обычный калькулятор показал бы 3.4, а Swift показал 3. Картинка с конфетами хорошо работает для положительных чисел. У отрицательных своё правило, и мы дойдём до него в разделе об остатке.
Пять арифметических операторов
Значок действия, например +, называют оператором. Для чисел в Swift их пять:
+складывает:7 + 2— это9;-вычитает:7 - 2— это5;*умножает:7 * 2— это14;/делит:7 / 2— это3;%даёт остаток от деления:7 % 2— это1.
Порядок действий такой же, как в математике: *, / и % выполняются раньше + и -. Скобки меняют порядок: 2 + 3 * 4 — это 14, а (2 + 3) * 4 — это 20.
Деление целых чисел
Когда оба числа имеют тип Int, результат тоже получается Int, а у Int нет дробной части. Такое деление называют целочисленным: дробная часть результата отбрасывается, а не округляется.
17 / 5— это3, хотя на бумаге выходит3.4.19 / 5— тоже3, хотя3.8ближе к четырём.-17 / 5— это-3, а не-4: у отрицательного результата дробная часть тоже отбрасывается.
Целочисленное деление всегда сдвигает результат к нулю. Так же в прошлой теме Int(2.9) превращался в 2, а Int(-2.9) — в -2.
Остаток и его знак
Оператор % даёт то, что осталось после целочисленного деления. Частное и остаток связаны: частное, умноженное на делитель, плюс остаток дают исходное число. Для конфет это 3 * 5 + 2, то есть 17.
Из этой связи следует правило для отрицательных чисел: знак остатка совпадает со знаком делимого, числа слева от %.
print(-17 / 5, -17 % 5) // -3 -2
print(17 / -5, 17 % -5) // -3 2Разберём обе строки:
- В первой строке частное равно
-3, а-3 * 5— это-15. До-17не хватает ещё-2— это и есть остаток. - Во второй строке делимое
17положительное, поэтому и остаток2положительный, хотя делитель отрицательный.
Этот вопрос любят задавать на собеседовании: какой знак у остатка, если делимое отрицательное? В математике остаток обычно считают неотрицательным, а в Swift он берёт знак делимого.
Оператор % работает только с целыми числами. Если применить его к Double, компилятор выдаст ошибку.
Дробный результат
Дробь получается, когда делят числа типа Double. Есть два способа её получить.
Дробное число в коде
Число с точкой, например 7.0, уже дробное. Число 2 рядом с ним Swift тоже прочитает как Double, и 7.0 / 2 даст 3.5.
Преобразование констант
У константы тип уже есть, и сам он не меняется. Поэтому оба числа переводят в Double до деления: Double(sweets) / Double(kids) даёт 3.4.
Составное присваивание
Запись score = score + 5 встречается так часто, что для неё есть сокращение: score += 5. Такие операторы называют составным присваиванием.
var score = 10
score += 5
score -= 3
score *= 2
print(score) // 24Разберём по строкам:
score += 5прибавляет 5: вscoreтеперь15.score -= 3вычитает 3: теперь там12.score *= 2умножает на 2: теперь там24.print(score)печатает24.
Составное присваивание меняет переменную, поэтому работает только с var.
Привычной по другим языкам записи score++ в Swift нет:
error: cannot find operator '++' in scope; did you mean '+= 1'?Компилятор сам подсказывает замену: score += 1.
Частая ошибка
Результат деления двух Int переводят в Double в надежде получить дробь:
let total = 7
let parts = 2
let wrong = Double(total / parts) // ✗
let right = Double(total) / Double(parts) // ✓
print(wrong, right) // 3.0 3.5Ошибки компиляции нет, но в wrong оказывается 3.0. Сначала выполняется total / parts, то есть целочисленное деление, и только его результат 3 становится Double. Переводить в Double нужно числа до деления, как в строке с right.
Главное
- Деление двух
Intотбрасывает дробную часть:17 / 5— это3, а-17 / 5— это-3. %даёт остаток, и его знак совпадает со знаком делимого:-17 % 5— это-2.- Чтобы получить дробь, в
Doubleпереводят числа до деления, а не результат. +=,-=и*=меняют переменную на месте, а оператора++в Swift нет.