
- •Длинная арифметика
- •Введение
- •1. Способы представления «длинных» чисел
- •2. Ввод-вывод "длинных" чисел
- •3. Сложение двух «длинных» чисел
- •4. Умножение «длинного» числа на «короткое»
- •5. Умножение «длинного» числа на «длинное»
- •6. Рекурсивный алгоритм умножения
- •7. Вычитание двух “длинных” чисел с учетом сдвига
- •8. Деление «короткого» числа на «короткое» столбиком
- •9. Деление «длинного» числа на «короткое» нацело с остатком
- •10. Сравнение двух “длинных” чисел
- •11. Задачи с решениями
- •12. Контрольные вопросы и упражнения
4. Умножение «длинного» числа на «короткое»
В подпрограмме для выполнения такого умножения будем использовать массив s, в качестве, как входного параметра, так и результата умножения. Массив имеет тип TLONG .
В первом элементе этого массива расположены четыре младшие цифры «длинного» числа. Переменная L будет содержать значение текущей длины этого массива.
«Короткое» число находится в целочисленной переменной п.
Несмотря на то, что и число п и элементы массива s можно представить в целом типе с максимальным числом разрядов (longint в Turbo-Pascal и long в С), максимального значения этого типа они достигать не могут, так как результат умножения любого ненулевого элемента массива s на п также не должен превышать максимальное значение того нее типа.
В приведенном ниже примере реализации подобной подпрограммы каждый элемент входного и выходного массива s должен быть меньше 10000, т.е. состоять не более чем из одной цифры 10000-ичной системы счисления (четырех десятичных цифр). Значение п нри этом может достигать 231:10000 = 200000. При уменьшении количества цифр у элементов s, значение п может быть увеличено, и наоборот. Умножение производится последовательно от младшего разряда к старшему в 10000-ичной системе счисления, каждая цифра которой записывается как число в десятичной системе, смешанной с ней.
procedure Mult (var s : along; var L : longint; n : longint);
{умножаем массив s длины L на число n}
Var pr,i:longint;
Begin
pr:=0; {перенос в старший 10000-ичный разряд}
for i := 1 to L do
begin
s[i] := s[i]*n;
s[i] := s[i]+pr;
pr := s[i] div 10000;
s[i] := s[i] mod 10000;
end;
while pr>0 do
begin
inc (L);
s[L] := pr mod 10000;
pr := pr div 10000
end
End;
Заметим, что результат мы получили в 10000-ичной системе счисления и при его выводе следует дополнять каждый элемент результирующего массива до четырех десятичных цифр ведущими нулями.
Пример такого вывода содержится, например, в решении задачи параграфа 7, использующей подпрограмму Mult.
Существует и другая возможность умножения “длинного” числа на “короткое”. Эта процедура очень похожа на процедуру сложения - точно так же моделируется вычислением в столбик, точно так же на каждом шаге определяется перенос в следующий разряд. Поэтому реализацию решения задачи можно вынести на самостоятельную работу учащимся.
Под “коротким” числом понимается целое число типа LongInt. "Длинное" чило располагается в массиве А типа TLong.
В первом элементе этого массива расположены четыре младшие цифры "длинного" числа.
Процедура будем иметь следующий вид:
Procedure Mul (Const A:TLong; Const K:LongInt; Var C:TLong);
Var i:Integer; {результат - значение переменной С}
Begin
FillChar (C, SizeOf (C), 0); {заполнение массива С нулями}
If K=0 Then Inc (C[0]) {умножение на ноль}
Else
Begin
For i:=1 To A[0] Do
Begin
{умножение длины массива А на чило K и "протаскивание" старшей цифры из C[i] в младшую цифру числа из C[i+1]}
C[i+1]:= (LongInt (A[i]*K+C[i]) Div Osn;
C[i]:= (LongInt (A[i]*K+C[i]) Div Osn;
End;
If C[A[0]+1] > 0 Then C[0]:=A[0]+1
Else C[0]:=A[0]
{определяем длину результат}
End;
End;