
- •Длинная арифметика
- •Введение
- •1. Способы представления «длинных» чисел
- •2. Ввод-вывод "длинных" чисел
- •3. Сложение двух «длинных» чисел
- •4. Умножение «длинного» числа на «короткое»
- •5. Умножение «длинного» числа на «длинное»
- •6. Рекурсивный алгоритм умножения
- •7. Вычитание двух “длинных” чисел с учетом сдвига
- •8. Деление «короткого» числа на «короткое» столбиком
- •9. Деление «длинного» числа на «короткое» нацело с остатком
- •10. Сравнение двух “длинных” чисел
- •11. Задачи с решениями
- •12. Контрольные вопросы и упражнения
3. Сложение двух «длинных» чисел
Напишем подпрограмму сложения двух «длинных» положительных чисел, представленных в виде массивов а и b типа TLong, описанного выше.
Будем считать, что каждый элемент такого массива содержит всего одну десятичную цифру. Первый элемент массива содержит младшую цифру. Результат будем помещать в массив c того же типа.
Сложение двух "длинных" чисел очень похоже на обычное школьное сложение столбиком. Числа складываются поразрядно. Сложение производится с помощью стандартного алгоритма сложения столбиком от младшего разряда к старшему с переносом единицы в старший разряд, если в результате сложения двух цифр и значения переноса из младшего разряда получается число, большее девяти.
Алгоритм процедуры сложения объясним на простом примере.
Пусть А = 870613029451, В = 3475912100517461.
Тогда при использовании уже известного представления "длинных" чисел получаем:
I A[i] B[i] C[1] C[2] C[3] C[4]
1 451 7461 6912 1 0 0
2 1302 51 6912 1354 0 0
3 8706 9121 6912 1354 7827 1
4 0 3475 6912 1354 7827 3476
Алгоритм имитирует привычное сложение столбиком, начиная с младших разрядов. И именно для простоты реализации арифметических операций над “длинными” числами используется машинное представление в обратном порядке.
Результат: С = 3476782713546912.
Тогда программа ввода двух “длинных” чисел и вывода результата их сложения будет иметь следующий вид:
Var
A, B, C: Tlong;
Procedure SumLongTwo (A, B: Nlong; Var C: Tlong;);
var i, k: integer;
Begin
FillChar (C, SizeOf (C),0);
{заполнение массива С нулями, т.к. неиспользованные разряды заполняются нулями}
if A[0]>B[0] then k:=A[0] {условие нахождения большего}
else k:=B[0]; {чисел из А и В}
for i:=1 to k do
begin
C[i+1]:= (C[i]+A[i]+B[i]) Div Osn;
C[i]:= (C[i]+A[i]+B[i]) Mod Osn;
end;
{производится сложение двух "длинных" чисел, причем целая часть от основания записывается в i+1 позицию, потому что в одном элементе массива хранится только четыре цифры}
if C[k+1]=0 then C[0]:=k {проверяется результат, выходит ли}
else C[0]:=k+1; {он за рамки разряда или нет}
end;
Begin
Assign (Input, ‘Input.txt');
{связывание файловой переменной с именем физического файла,
Input- имя файловой переменной, Input.txt- строковое выражение, определяющее имя физического файла}
Reset (Input); {открыть для ввода данных}
ReadLong (A); {обращение к процедурам ввода "длинных"}
ReadLong (B); {чисел А и В}
Close (Input); {закрыть файл}
SumLongTwo (A,B,C); {обращение к процедуре сложения двух "длинных" чисел}
Assign (Output, ‘Output. txt’);
{связывание файловой переменной с именем физического файла; Output - имя файловой переменной, Output.txt- строковое выражение, определяющее имя физического файла}
Rewrite (Output); {открыть для вывода на экран}
WriteLong (C); {обращение к процедурам вывода результата}
Close (Output); {закрыть файл}
end.
После изложения материала, слушателям предлагаются следующие вопросы для закрепления материала:
1. Что произойдет, если сумма A[i]+B[i] окажется больше максимально допустимого значения типа Tlong? Как можно этого избежать?
2. Напишите алгоритм сложения двух "длинных" чисел?