Главная Случайная страница


Полезное:

Как сделать разговор полезным и приятным Как сделать объемную звезду своими руками Как сделать то, что делать не хочется? Как сделать погремушку Как сделать так чтобы женщины сами знакомились с вами Как сделать идею коммерческой Как сделать хорошую растяжку ног? Как сделать наш разум здоровым? Как сделать, чтобы люди обманывали меньше Вопрос 4. Как сделать так, чтобы вас уважали и ценили? Как сделать лучше себе и другим людям Как сделать свидание интересным?


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Деление «короткого» числа на «короткое» столбиком





Задача деления двух целых чисел заключается в нахождении целой части частного и остатка. Поэтому для начала нужно вспомним целочисленное деление и деление с остатком.

Сделаем это на основе следующего примера:

_1000143123567 | 73859998

73859998 13541 (Целая часть частного)

_261543143

221579994

_399631495

369299990

_303315056

295439992

_ 78750647

73859998

4890649 (Остаток)

 

Что мы делали? На каждом этапе в уме подбирали цифру (1, 3, 5 и т. д.), такую, что произведение этой цифры на делитель дает число меньшее, но наиболее близкое к исходному числу... Зачем нам это делать в уме, пусть делает компьютер. Да, мы ему не поможем. Однако упростим пример, оставим его упрощенный вид для тестирования окончательной логики процедуры, тем более что и числа “длинны”.

Пусть число А будет меньше В•10, тогда в результате (целой части деления) будет одна цифра. Например, А равно 564, а В - 63 и простая десятичная система счисления.

Попробуем подобрать цифру результата, но не методом прямого перебора, а методом деления отрезка пополам.

Пусть Down - верхняя граница интервала изменения подбираемой цифры, Up - нижняя граница интервала, Ost равен делимому. Эту попытку, подбора результата с помощью метода деления отрезка пополам, можно записать в следующую таблицу:

 

Down Up C=B• ((Down+Up) Div 2) Ost = 564

0 10 315 = 63• ((0+10) Div 2) C < Ost

5 10 441 = 63• ((5+10) Div 2) C < Ost

7 10 504 = 63• ((7+10) Div 2) C < Ost

8 10 567 = 63• ((8+10) Div 2) C > Ost

8 9 504 = 63• ((8+9) Div 2) C < Ost

 

Итак, результат - целая часть частного - равен (Up + Down) Div 2, остаток от деления - разность между значениями Ost и C. Нижнюю границу (Down) изменяем, если результат (С) меньше остатка, верхнюю (Up), если больше.

Усложним пример. Пусть А равно 27856, а В - 354. Основанием системы счисления является не 10, а 10000. Выполним подбор результат для этого примера, как мы сделали выше.

Получим следующую таблицу, в которой у нас есть значения Down- верхней границы интервала изменения подбираемой цифры, Up- нижняя граница интервала, Ost равен делимому. Результат вычисляется так же как и в верхней таблице, с помощью метода деления отрезка пополам.

 

Down Up C Ost = 27856

0 10000 1770000 С > Ost

0 5000 885000 C > Ost

0 2500 442500 C > Ost

0 1250 221250 C > Ost

0 625 110448 C > Ost

0 312 55224 C > Ost

0 156 27612 C < Ost

78 156 41418 C > Ost

78 117 34338 C > Ost

78 97 30798 C > Ost

78 87 29028 C > Ost

78 82 28320 C > Ost

78 80 27966 C > Ost

78 79 27612 C < Ost

 

Целая часть частного равна 78, остаток от деления - 27856 минус 27612, т. е. 244.

Итак, можно привести процедуру. В процедуру входят: функция сравнения чисел (More) с учетом сдвига и функция умножения длинного числа на короткое (Mul) (см. примеры, рассмотренные ранее).

 

Function FindBin (Var Ost:TLong; Const B:TLong; Const sp:Integer):LongInt;

Var Down, Up:Word;

C:TLong;

Begin

Down:=0;

Up:=Osn; {основание системы счисления}

While Up-1>Down Do

Begin

{Есть возможность сделать сознательную ошибку. Изменить условие цикла на Up>Down. Результат - зацикливание программы.}

Mul (B, (Up+Down) Div 2, C);

{обращения к процедуре умножения "длинного" числа на короткое}

Case More (Ost, C, sp) Of

{выбираем один из выполняемых операторов, который удовлетворяет условиям функции сравнения остатка и результата, т.е. нижнюю границу (Down) изменяем, если результат (С) меньше остатка, верхнюю (Up), если больше.}

0: Down:= (Down+Up) Div 2;

1: Up:= (Up+Down) Div 2;

2: Begin

Up:= (Up+Down) Div 2;

Down:= Up;

End;

End;

End;

Mul (B, (Up+Down) Div 2, C);

If More (Ost, C, 0) = 0 Then Sub (Ost, C, sp)

{находим остаток от деления}

Else

begin

Sub (C, Ost, sp);

Ost:=C;

FindBin:= (Up+Down) Div 2;

{целая часть частного}

End;

End;

 

Осталось разобраться со сдвигом, значением переменной sp в нашем изложении. Опять вернемся к обычной системе счисления и попытаемся разделить, например, 635 на 15.

Что мы делаем? Вначале делим 63 на 15 и формируем, подбираем в уме первую цифру результата (подбирать с помощью компьютера мы тоже научились). Подобрали - это цифра 4, и это старшая цифра результата.

Изменим остаток. Если вначале он был 635, то сейчас стал 35. Вычитать с учетом сдвига мы умеем. Опять подбираем цифру. Вторую цифру результата. Это цифра 2 и остаток 5. итак, результат (целая часть) 42, остаток от деления 5.

А что изменится, если основанием будет не 10, а 10000? Логика совпадает, только в уме считать несколько труднее, но так как есть компьютер, то можно вычисления произвести на нем.

Итак, все необходимо для написания процедуры деления двух "длинных" чисел у нас есть. Это процедура выглядит следющим образом:

 

Procedure MakeDel (Const A, B:TLong; Var Res, Ost:TLong);

Var sp:Integer;

Begin

Ost:=A; {первоначальное значение остатка}

sp:=A[0]-B[0];

If More (A, B, sp) = 1 Then Dec (sp);

{B*Osn>A, в результате одна цифра}

Res[0]:=sp+1;

While sp>=0 Do

Begin

{находим очередную цифру результата}

Res[sp+1]:= FindBin (Ost, B, sp);

Dec (sp);

End;

End;

 

 

Рассмотрим более общую ситуацию.

Несмотря на то, что исходные данные являются «короткими» числами, задача их деления относится к разряду алгоритмов длинной арифметики, так как результатом может оказаться число, которое состоит из бесконечного количества цифр (периодическая дробь).

Эту задачу можно решать в двух постановках. Если результатом деления является конечная или периодическая дробь, то результат можно получать в алгебраической форме, т.е. с выделением непериодической части и периода.

При делении произвольного натурального числа на другое натуральное число соответствующая данному действию обыкновенная дробь может оказаться неправильной, и результат будет содержать ненулевую целую часть. Поэтому, после считывания значений делимого т и делителя п следует распечатать значение т div п и запятую, потом заменить т на остаток от такого деления (т:=т mod п).

При выводе дробной части результата надписи о наличии или отсутствии непериодической части можно опустить, а перед началом выдачи периода следует напечатать «(». Вывод следует завершить символом «)». Если же период отсутствует, то его лучше не печатать совсем.

Другой постановкой задачи может являться просто получение целой части и заранее фиксированного количества цифр дробной части, т.е. решение задачи с желаемой точностью. Программа при этом оказывается значительно более простой.

 

Var

m,n,i,k:longint;

Begin

write(' Введите делимое:');

readln(m);

write(' Введите делитель:');

readln(n);

write(' Введите количество цифр в дробной части:'); readln(k);

write (m div n, ',');

m:= m mod n;

for i:= 1 to k do

begin

write (10*m div n);

m:= 10*m mod n;

if m=0 then break

end;

writeln;

End.

 

Заметим, что более корректным было бы не просто печатать последнюю из k цифр дробной части, а в зависимости от значения (k +1)-й цифры округлять результат (т.е. увеличивать его на единицу в случае когда (k +1)-я цифра больше четырех. Но тогда результат надо было бы предварительно запоминать, а потом использовать процедуру прибавления единицы к «длинному» числу.

 

Date: 2015-05-08; view: 655; Нарушение авторских прав; Помощь в написании работы --> СЮДА...



mydocx.ru - 2015-2024 year. (0.005 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию