Разработка программы-калькулятора дробей 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Разработка программы-калькулятора дробей



Формулировка задания

Требуется разработать программу-калькулятор дробей: fc (fraction calculator), который обеспечивает выполнение арифметических операций (сложение, вычитание, умножение и деление) для рациональных дробей, заданных в символическом формате. Программа fc должна быть ориентированна на использование следующего формата дробей: a/b, где a и b наборы цифр, отображающие числитель и знаменатель дроби.

Исходными данными программы fc являются последовательности символов, представляющие вычисляемые арифметические выражения, где дробные операнды связывает символ операции(+, -, *, /). Дробные операнды и символ операции должны передаваться программе fc, через параметры командной строки её вызова. В командной строке операнды и символ операции разделяются с помощью пробелов.

Результатом работы программы fc должно быть дробное число, которое представляет итог вычисления входного выражения и отображается в потоке стандартного вывода (stdout). Для некоторых операций и операндов должен быть предусмотрен вывод соответствующих информационных сообщений в поток протокола стандартной диагностики (stderr).

Программа fc должна быть составлена в системе программирования C++ на основе разработки специального класса, в котором перегружены специальные арифметические операции над дробными числами (выполнена перегрузка операций).

Свойства дробных чисел

В некоторых алгоритмах численной обработки данных более полезным является точное выражение результата в виде дроби (например, 1/3), чем приближенное представление с плавающей точкой (0,33333...). Использование дробей позволяет получить нецелочисленный ответ задачи в наглядной форме и исключить ошибку округления, свойственные обработке чисел с плавающей точкой в ограниченной разрядной сетке. Как известно, дробное число образует отношение 2-х целых чисел, которое записывается следующем образом: a/b, где a и b - наборы цифр, представляющие числитель и знаменатель дроби. Относительно числителя и знаменателя дроби приняты следующие договоренности:

· знаменатель дроби должен быть натуральным числом (b>0);

· целое число можно представить дробью с единичным знаменателем (a/1);

· знак дроби определяется знаком числителя;

· если числитель и знаменатель дроби умножить на одно и тоже натуральное число (N), то получиться дробь равная данной (a/b=(N*a)/(N*b));

· если числитель и знаменатель дроби имеют общий делитель, то при делении их на него происходит сокращение дроби и образуется дробь равная данной (D*a)/(D*b)=a/b);

· если числитель и знаменатель взаимно-простые числа, т. е. не имеют общих делителей, то дробь называется несократимой;

· любая дробь может быть представлена к несократимой, если её числитель сократить на их наибольший общий делитель (Hog) - наибольшее натуральное число, на которое они оба делятся без остатка;

· две любые дроби a/b и c/b считаются равными, если (a*d)=(b*c);

· две несократимые дроби считаются равными, если равны их числители и знаменатели (a=c и b=d).

Вычислительная обработка дробных чисел основана на использовании 4-х арифметических операций: сложение, вычитание, умножение и деление. Для выполнения этих операций символическое представление дроби выражается парой целых чисел, соответствующих её числителю и знаменателю. Пусть U/U' и V/V' обозначают дроби-операнды, а W/W'-дроби, результат операции. Тогда числитель и знаменатель результирующей дроби для 4-х арифметических операций выражают следующие соотношения:

Умножение:

(W/W')={(U/U')*(V/V')}

W=(U/d1)*(V/d2) и W'=(U'/d2)*(V'/d1), где d1=Hog(U,V') и d2=Hog(U'/V).

Деление: (W/W')={(U/U')/(V/V')}

W=(U/d1)*(V'/d2)sign(V) и W'=|(U'/d2)*(V/d1)|, где d1=Hog(U,V) и d2=Hog(U',V').

Сложение: (W/W')={(U/U')+(V/V')}

Если Hog(U'/V')=1,то

W=(U*V')+(U'*V) и W'=(U'*V')

Если Hog(U'/V')>1,то

W=t/d2 и W'=(U'/d1)*(V'/d2), где d1=Hog(U',V'), t=U*(V'/d2)+V*(U'/d1) и d2=Hog(t,d1).

Вычитание: (W/W')={(U/U')-(V/V')}. Выполняется аналогично сложению, если везде заменить знак плюс на знак минус.

В приведенных соотношениях Hog(m,n) обозначает наибольший общий делитель чисел |m| и |n|. Для эффективного вычисления Hog применяется алгоритм Евклида - самый старый нетривиальный алгоритм, доживший до наших дней. В современной редакции псевдокод алгоритма Евклида выглядит следующим образом:

Пример 1

IF m<0 THEN

m <- |m|; /* перейти к абсолютной величине числа m */

IF n<0 THEN

n <- |n|; /* перейти к абсолютной величине числа n */

WHILE n<>0 { /* цикл уменьшения n */

r <- m mod n; /* остаток деления m на n */

m <- n;

n <- r;

}

RETURN m.

В классическом варианте алгоритм Евклида используется для поиска наибольшего общего делителя пары не отрицательных целых чисел, при условии, что Hog(0,0) принимается равным 0. Для расширения области применения на поле произвольных целых чисел в предлагаемой версии алгоритма Евклида предусмотрен переход к абсолютным величинам рассматриваемых чисел. На каждом шаге основного цикла алгоритма Евклида происходит последовательное уменьшение обоих чисел, но при этом значение их наибольшего общего делителя остается неизменным, т. к.:

.

Цикл уменьшения обоих чисел продолжается, пока на очередной итерации меньшее из чисел не станет равным 0. В этом случае большее из чисел принимается за наибольший общий делитель исходной пары, т. к.:

.

Пример 2

Hog(259,111) выполняется за 3 шага: Hog(259,111)=Hog(111,37)=Hog(3,0)=3.

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

На первый взгляд кажется, что арифметические операции над дробями можно реализовать более эффективно, вычисляя наибольший общий делитель в каждой операции только один раз вместо двух. Например, при умножении {(U/U')*(V/V')}, числитель и знаменатель ответа можно получить по внешне более простым формулам:

где .

При сложении 2-х дробей {(U/U')+(V/V')} можно представить результат в виде следующей дроби:

а затем привести результирующую дробь к не сократимому виду, используя свойство:.

Однако, в обоих случаях придется оперировать с относительно большими числами на каждой итерации алгоритма Евклида. Каждая итерация будет выполняться медленнее, чем код на в ней рассматриваются меньшие числа, которые характерны для операций обработки дробей с 2-мя вычислениями наибольшего общего делителя. Таким образом, по быстродействию оба подхода по-крайней мере равнозначны, но в первом исключена возможность переполнения разрядной сетки, что является решающим преимуществом, когда числители и знаменатели дробей являются большими числами.



Поделиться:


Последнее изменение этой страницы: 2021-07-18; просмотров: 36; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 52.14.224.197 (0.007 с.)