Многоразрядные числа и длинная арифметика
Как считать с числами, которые не помещаются ни в один тип.
11 класс, углублённый уровень — пара шестнадцатая.
Уроки 31–32 поурочного плана: «Многоразрядные целые числа, задачи длинной
арифметики» и практическая работа «Реализация вычислений с многоразрядными
числами». На прошлой паре искали простые числа до миллионов. Сегодня — числа
в сотни и тысячи цифр: как их хранить и как с ними считать.
Когда числа не помещаются
| целый тип | наибольшее число | цифр |
| 32 бита (int в C++) | 2 147 483 647 | 10 |
| 64 бита (long long) | 9 223 372 036 854 775 807 | 19 |
264 = 18 446 744 073 709 551 616 — 20 цифр.
25! = 15 511 210 043 330 985 984 000 000 — 26 цифр.
Ключ шифрования RSA на 2048 бит — число из 617 цифр.
С ним нужно складывать, умножать, делить с остатком.
Длинная арифметика — храним число по частям и
считаем столбиком, как на бумаге. В Python тип

длинный сам:

считается точно. Внутри он тоже хранит число частями
— так, как мы сейчас разберём.
Как хранить длинное число
Список цифр младшими вперёд: первой стоят единицы, потом
десятки, сотни…
8497 → 
a[i] — цифра при 10i: номер элемента совпадает с
номером разряда.
Почему не старшими вперёд: столбик идёт от
единиц, а новый старший разряд при переносе просто дописывается в конец —

. Сдвигать список не нужно.
Блоками по несколько цифр
Хранить по одной цифре расточительно: в элемент списка помещается и 3, и
4, и 9 цифр. Блоки по три цифры — это система счисления с основанием 1000.
Ловушка: блок внутри числа — ровно три цифры. 45 — это
045, 7 — это 007. Без нулей 3 120 045 007 превратится в
3 120 45 7.
Блоков в три раза меньше, чем цифр, — и действий над
ними тоже в три раза меньше. Число из 617 цифр блоками по 9 — всего 69
элементов.
Сложение столбиком
Идём от младшего разряда. В разряд пишем последнюю цифру суммы, а
перенос уходит в следующий разряд.
- x = a[i] + b[i] + p, цифра — x % 10, перенос — x // 10.
- Перенос при сложении — 0 или 1: больше 9 + 9 + 1 = 19 не бывает.
- Перенос из старшего разряда — новая цифра: сумма n-значных бывает
n + 1-значной.
9 586 + 4 735
Над разрядами — переносы: их четыре, последний стал новой
цифрой.
Вычитание и умножение на однозначное
Вычитание — заём
Цифра меньше вычитаемой — занимаем единицу у старшего разряда и
прибавляем 10. Над разрядом, у которого заняли, — «−1».
Четыре займа: нули сами занимают у соседа.
Умножение на цифру
x = a[i]·d + p, цифра — x % 10, перенос — x // 10. Перенос бывает до 8:
9·9 + 8 = 89.
0·7 + 6 = 6 — перенос ноль; ненулевых переносов три.
Сложение в программе
a — это 8497, b — 865, оба младшими вперёд. Список a не
короче b;
— когда цифры b кончились.
Строки

после
цикла — перенос из старшего разряда. Без них 9586 + 4735 дало бы 4321.
Умножение длинного на короткое
4096·7 = 28 672: a станет [2, 7, 6, 8, 2]. Цифры пишутся
прямо на место старых.
Почему

, а не

: множитель
может быть больше 9, и перенос тогда многозначный. При d = 25 последний
перенос может быть 24 — это две цифры.
Умножили на 2 сорок раз подряд, начиная с

, — в списке 2
40. Так считают степени и
факториалы любой длины.
Сколько цифр и сколько это стоит
Сколько цифр
У натурального x цифр ⌊lg x⌋ + 1. У mn — ⌊n·lg m⌋ + 1.
2100: 100·0,30103 = 30,103 → 31 цифра.
Произведение m-значного и n-значного — m + n − 1 или m + n:
10·10 = 100, 99·99 = 9801.
Сколько действий
Сложение n-значных — по действию на разряд: порядка n.
Умножение столбиком m-значного на n-значное — каждая цифра на каждую:
порядка m·n.
Блоки по k цифр сокращают сложение в k раз, а умножение — в
k·k раз.
lg 2 ≈ 0,30103, lg 3 ≈ 0,47712, lg 7 ≈ 0,84510. Целая
часть логарифма — это цифр минус один: lg 100 = 2, а цифр три.
Практическая работа: числа в тысячи цифр
int в Python длинный: 71234 — число из 1043 цифр,
считается мгновенно. Строка s — его десятичная запись.
| что спросили | что печатаем |
| сумма цифр | k после цикла по s |
| сколько цифр | len(s) |
| сколько раз цифра 0 | s.count('0') |
| первые пять цифр | s[:5] |
| n! или Фибоначчи | сначала цикл, потом str() |
Проверь программу на маленьком: 2 ** 10 = 1024 —
четыре цифры, сумма 7. Python 3.11 и новее не переводит в строку числа
длиннее 4300 цифр — в практикуме числа короче.
То же своим списком цифр
Это 25! без длинного int: список умножается на 2, 3, …, 25 тем же
столбиком. Напечатает 26 — столько цифр в 25!.
Так длинная арифметика реализуется в любом языке.
Свою программу сверь с

на int: ответы обязаны
совпасть. Сумма цифр —

, первые цифры — с конца
списка.
Что верно, а что нет
Верно
- Цифры удобно хранить младшими вперёд.
- Сумма двух n-значных — не больше n + 1 цифры.
- Умножение столбиком — порядка m·n действий.
- int в Python длинный сам.
Неверно
- «Перенос при сложении бывает 2». Не больше 1.
- «[3, 2, 1] младшими вперёд — это 321». Это 123.
- «Блок 5 внутри числа — это 500». Это 005.
- «У 2n ровно n цифр». У 210 — четыре.
Что делаем дальше
- Обзорный практикум — шесть задач, все сразу на странице, в любом
порядке: понятия, переносы и займы столбиком, длинное число в списке,
что напечатает программа, сколько цифр, практическая работа.
- Столбики — на черновике, как на слайдах. Код в задачах — картинкой,
его читают.
- Шестой вопрос — практическая работа: свою программу пишем в IDLE.
- Ответ везде — целое число, без пробелов между разрядами.
Отметка: закрыто 6 из 6 — «5», 5 — «4», 3 или 4 — «3». Исправленная задача не
засчитывается — за ошибку приходит новая, добирать можно до пятёрки.
За работу
Практикум «Многоразрядные числа и длинная арифметика» — в общей
папке и на сайте. Не успел на уроке — пройди дома: вариант будет другой, сдаётся
тем же кодом.
Карточку в тетрадь можно взять с собой: на ней хранение числа списком,
правила столбика, сколько цифр у результата и образцы программ.