Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лк13 Длинная арифметика.doc
Скачиваний:
87
Добавлен:
28.10.2018
Размер:
252.93 Кб
Скачать

9. Деление «длинного» числа на «короткое» нацело с остатком

Решение этой задачи мало отличается от предыдущей, поэтому дадим лишь некоторые пояснения к приведенным ниже программам.

Так как делить на этот раз мы будем «длинное» число, входные данные удобнее представлять в файле. Входным файлом в данной задаче является файл input.txt, а выходным — output.txt.

Делимое при вводе из файла в подпрограмме ReadData запоминается в массиве а (в первом элементе старшая цифра), делитель — в целой переменной b, а целую часть результата будем получать в массиве с (в первом элементе также находится старшая цифра).

Нулевые элементы массивов a и с содержат значения текущей длины этих массивов (а[0] — заполняется при считывании делимого из файла, а с[0] — при получении целой части результата). Так как делитель у нас является числом «коротким», а остаток от деления всегда меньше делителя, то для его получения массив не нужен.

Туре

Abyte=array[0..32000] of byte;

Var

а,с: AByte;

b,p: longint;

Procedure ReadData;

var

ch:char;

begin

Assign(input,'input.txt');

Reset(input);

a[0] := 0; {длина числа А}

c[0] := 0; {длина числа С}

while not SeekEoln do {пока не достигнут конец строки}

begin

read(ch);

inc (a[0]); {перевод символа в цифру}

а[а[0]]:=ord(ch)-ord('0')

end;

readln;

read(b);

Close(input)

end;

Procedure Count;

var

ptr: word;

begin

p:=0;

ptr:=1;

while (p<b) and (ptr<=a[0]> do

begin

p:=p*10+a[ptr];

inc(ptr)

end;

inc(c[0]); {с[0] — длина целой части частного}

с[с[0]] := р div b; {определили первую цифру частного}

р := р mod b;

while ptr<=a[0] do

{определяем остальные цифры частного}

begin

р:=p*10+а[ptr];

inc(ptr);

inc(c[0]);

c[c[0]] := p div b;

p := p mod b

end

end;

Procedure WriteResult;

var

i: word;

begin

assign(Output,'Output.txt');

rewrite(Output);

for i:=l to c[0] do write (с[i]); {печатаем целую часть частного от деления}

writeln;

writeln(p); {печатаем остаток от деления}

end;

{Основная программа}

Begin

ReadData;

Count;

WriteResult

End.

10. Сравнение двух “длинных” чисел

Сравнения "длинных" чисел похожи на сравнения простых чисел и не представляют большой сложности. Рекомендуется реализации операций сравнения изучить самостоятельно.

Приведем примеры реализаций операций сравнения для “длинных” чисел.

Function Eq (A, B: TLong): Boolean;

Var i: Integer;

Begin

Eq:=False;

If A[0]<>B[0] Then Exit {если числа не равны, то выходим из программы}

Else

Begin

{иначе, пока выполняется условие, что каждая цифра значения элемента A[i] равны каждой цифре элемента B[i], значение i увеличиваем на 1, итак пока не будут проверены массивы до конца}

i:=1;

While (i<=A[0]) And (A[i]=B[i]) Do Inc (i);

Eq:= (i=A[0]+1);

End;

End;

Реализация функции A > B также прозрачна.

Function More (A, B: TLong): Boolean;

Var i:Integer;

Begin

{сравниваем длины чисел А и В (мы еще говорили, что в A[0] элементе массива хранится длина числа}

If A[0]<B[0] Then More:= False

Else

If A[0]>B[0] Then More:= True

Else

Begin

i:= A[0];

While (i>0) And (A[i]=B[i]) Do Dec (i);

{проверяем каждый элемент массива сравнивая их друг с другом}

If i=0 Then More:=False

Else

If A[i]>B[i] Then More:=True

Else More:=False;

End;

End;

Остальные функции реализуются через функции Eq и More.

Function Less (A, B:TLong):Boolean; {A<B}

Begin

Less:=Not (More (A, B) Or Eq (A, B));

End;

Function More_Eq (A, B:TLong):Boolean; {AB}

Begin

More_Eq:=More (A, B) Or Eq (A, B);

End;

И, наконец, последняя функция АВ.

Function Less_Eq (A, B:TLong):Boolean;

Begin

Less_Eq:=Not (More (A, B) );

End;

Для самостоятельного решения может быть предложена следующая, более сложная, задача.

Требуется разработать функцию, которая выдает 0, если А больше В, если А меньше В, и 2 при равенстве чисел. Но сравнение должно быть выполнено с учетом сдвига.

О чем идет речь? Поясним на примере. Пусть А равно 56784, а В - 634. При сдвиге числа В на 2 позиции влево функция должна сказать, что В больше А, без сдвига, что А больше В.

Другой пример. При А равном 56700, а В - 567 и сдвиге 2 функция должна “сказать”, что числа равны.

Решение иметь следующий вид:

Function More (Const A, B:TLong; Const sdvig:Integer):Byte;

Var i:Integer;

Begin

If A[0]>(B[0]+sdvig) Then More:=0

Else

If A[0]<(B[0]+sdvig) Then More:=1

Else

Begin

i:=A[0];

While (i>sdvig)And(A[i]=B[i-sdvig]) Do Dec (i);

More:=0;

If i=sdvig

Then

Begin

{совпадение чисел с учетом сдвига}

For i:=1 To sdvig Do

If A[i] > 0 Then Exit;

More:=2; {числа равны, “хвост” числа А равен нулю}

End

Else More:=Byte (A[i] < B[i-sdvig]);

End;

End;