Арифметика целых чисел
Склад считает в штуках: товары, коробки, заказы, копейки. Это целые числа, и у их арифметики в Go есть особенность — деление.
Пять операторов
Ситуация. На складе 17 товаров, в коробку помещается 5: сколько будет полных коробок и сколько товаров останется?
package main
import "fmt"
func main() {
fmt.Println(17 + 5)
fmt.Println(17 - 5)
fmt.Println(17 * 5)
fmt.Println(17 / 5)
fmt.Println(17 % 5)
}Что увидите.
stagiaire@lab:~/gocourse/day03/scratch$ go run .
22
12
85
3
2Как это читать. Сложение, вычитание и умножение — как в школе. / у целых чисел даёт целую часть деления, % — остаток: 17 / 5 — три полные коробки, 17 % 5 — два товара без коробки (3 * 5 + 2 = 17).
Целое деление отбрасывает дробь
В математике 17 / 5 = 3.4. В Go, если оба числа целые, результат тоже целый, и дробь отбрасывается, а не округляется: 3.8 тоже стало бы 3. С отрицательными числами отбрасывание идёт к нулю:
fmt.Println(-7/2, -7%2, 7/-2, 7%-2)-3 -1 -3 1-7 / 2 в математике -3.5; дробь отброшена — вышло -3, а не -4. Остаток такой, чтобы сходилась проверка «частное × делитель + остаток = делимое»: -3 * 2 + (-1) = -7. Отсюда правило: знак остатка — как у делимого. Складу дробь и не нужна: 3.4 коробки не бывает.
Попробуйте сейчас: что выведет деление целых?
Цель: предсказать вывод деления и остатка без запуска и отправить ответ.
Предскажите вывод, не запуская:
Код для чтения · разбираем, набирать не нужноpackage main import "fmt" func main() { fmt.Println(9/4, 9%4, -9/4) }▶ Выполните · выделенное замените своимcourse answer day03.q1 ВАШ_ОТВЕТВместо
ВАШ_ОТВЕТ— строка вывода целиком, как её напечатает программа.После ответа проверьте себя запуском — программу нужно набрать в
scratch/main.go:✎ Наберите в файлscratch/main.gopackage main import "fmt" func main() { fmt.Println(9/4, 9%4, -9/4) }▶ Выполнитеcd ~/gocourse/day03/scratch go run .Разошлось с вашим ответом — отправьте ответ заново, засчитывается последний.
Готово, когда: ответ отправлен — пункт проверки
q1.
Порядок действий
Как в школе: сначала скобки, потом *, / и % слева направо, потом + и -.
fmt.Println(2+3*4, (2+3)*4)
fmt.Println(100-20*3/4, 7*10/4, 7/4*10)14 20
85 17 10Как это читать.
| Выражение | Шаги | Итог |
|---|---|---|
2+3*4 |
3*4 = 12, 2+12 |
14 |
(2+3)*4 |
скобки: 5, 5*4 |
20 |
100-20*3/4 |
20*3 = 60, 60/4 = 15, 100-15 |
85 |
7*10/4 |
7*10 = 70, 70/4 — это 17.5, дробь отброшена |
17 |
7/4*10 |
7/4 — это 1.75, дробь отброшена: 1, 1*10 |
10 |
Последние два выражения отличаются только порядком — и дают 17 и 10: в 7/4*10 дробь потерялась в середине расчёта, и умножение её не вернёт. Отсюда правило, которое понадобится на пятой странице: сначала умножать, потом делить. Пробелы вокруг операторов ставит gofmt, на результат влияют только скобки.
Попробуйте сейчас: что выведет порядок действий?
Цель: предсказать вывод с порядком действий и отправить ответ.
Код для чтения · разбираем, набирать не нужноpackage main import "fmt" func main() { items := 50 fmt.Println(items-8*3/4, (items-8)*3/4) }▶ Выполните · выделенное замените своимcourse answer day03.q2 ВАШ_ОТВЕТВместо
ВАШ_ОТВЕТ— строка вывода целиком.После ответа проверьте себя запуском — программу нужно набрать в
scratch/main.go:✎ Наберите в файлscratch/main.gopackage main import "fmt" func main() { items := 50 fmt.Println(items-8*3/4, (items-8)*3/4) }▶ Выполнитеcd ~/gocourse/day03/scratch go run .Разошлось — отправьте ответ заново, засчитывается последний.
Готово, когда: ответ отправлен — пункт проверки
q2.
Рубли и копейки
Цены в курсе хранятся в копейках, целым числом (почему — на пятой странице), а рубли и копейки достаются делением и остатком:
price := 12305
fmt.Println(price/100, "руб.", price%100, "коп.")123 руб. 5 коп.12305 / 100 — сколько целых сотен копеек, то есть рублей, 12305 % 100 — что осталось. На чеке пишут «05 коп.»: как напечатать ведущий ноль — на четвёртой странице.
Трассировка с арифметикой
Таблица трассировки из дня 02 показывает по шагам, что лежит в переменных.
package main
import "fmt"
func main() {
stock := 250
orders := 7
perOrder := stock / orders
left := stock % orders
stock = stock - perOrder*orders
fmt.Println(perOrder, left, stock)
}Номер строки считается от начала файла, включая пустые: package main — строка 1, stock := 250 — строка 6; если первой строкой стоит комментарий, как в trace/main.go, номера сдвигаются на одну.
Формат — из дня 02: шапка-комментарий с #, колонка на каждую переменную, строка таблицы на каждую выполненную строку main, включая печать:
# шаг | строка | stock | orders | perOrder | left
1 | 6 | 250 | - | - | -
2 | 7 | 250 | 7 | - | -
3 | 8 | 250 | 7 | 35 | -
4 | 9 | 250 | 7 | 35 | 5
5 | 10 | 5 | 7 | 35 | 5
6 | 11 | 5 | 7 | 35 | 5Как это читать. В колонке — что лежит в переменной после строки, - — переменной ещё нет. Шаг 3: 250 / 7 — это 35.7…, дробь отброшена. Шаг 4: 35 * 7 = 245, до 250 не хватает 5. Шаг 5: справа от = берётся старое значение stock, 250. Шаг 6 — печать: значения переписаны из шага 5.
Что может пойти не так
| Что видите | Что это значит | Что делать |
|---|---|---|
получилось 10, ожидали 17 |
деление раньше умножения, дробь потеряна в середине | сначала умножить, потом делить |
получилось 14, ожидали 20 |
умножение раньше сложения | поставить скобки |
Все ? заполнены, но где-то значение не совпало |
ошибка в шаге: часто в колонке, которую шаг не менял, или на строке печати | несменившиеся значения переписать из строки выше |
Строк с шагами в таблице 8, а нужно 7 |
строку удалили, добавили или сняли # с шапки |
меняются только ? |
Попробуйте сейчас: задание
boxes.Цель:
boxes/main.goсама считает коробки и остаток по числам изTASK.txt.
- Прочитайте условие — числа у вас свои:
▶ Выполнитеcd ~/gocourse/day03/boxes cat TASK.txt
- Создайте в папке
boxesфайлmain.go: числа из условия — в переменные, коробки и остаток — выражения из них. Проверка подставит в копию другие числа, и готовые ответы не пройдут.- Запустите и сравните вывод с примером из
TASK.txt:▶ Выполнитеgo run .Готово, когда: вывод совпал с примером из
TASK.txtстрока в строку — пунктboxes.
Попробуйте сейчас: трассировка задания
trace.Цель: в
trace/table.txtвсе?заменены значениями, найденными без запуска.
- Посмотрите программу — числа в ней ваши:
▶ Выполнитеcd ~/gocourse/day03/trace cat main.go
- Откройте
table.txtв VS Code: шаги, номера строк и прочерки вписаны — замените каждый?значением переменной после строки, в уме, без запуска. Особое внимание шагу 4.- Номера строк — по
main.goкак он лежит, поэтому файл не меняйте; отладочную печать добавляйте в копию:▶ Выполнитеcp main.go ~/gocourse/day03/scratch/main.go
- Заполнив таблицу, запустите программу:
rubиkopиз последней строки должны совпасть с выводом.▶ Выполнитеcd ~/gocourse/day03/trace go run .Готово, когда: в
table.txtне осталось?, аrubиkopиз последней строки совпали с выводом — пунктtrace.
Дальше: дробные числа и преобразования типов — course next