Консультация № 183984
07.09.2011, 15:44
61.10 руб.
0 17 2
Здравствуйте! Помогите мне сделать задание???
Задание:
Написать модуль работы с обыкновенными дробями.
И прокомментрируйте пожалуйста почти каждую команду в коде.

Обсуждение

Неизвестный
07.09.2011, 16:39
общий
Уточните пожалуйста задание - ограничения, операции, форма представления и пр...
Текущая формулировка вопроса слишком "обща" для реализации.
Неизвестный
07.09.2011, 17:18
общий
Вот как бы полное задание:
Написать и отранслировать в индивидуальном задании модуль.
Разработать документацию на модуль с описанием его назначения формы представления информации включая в процесс функции и алгоритмов работы.
Неизвестный
07.09.2011, 17:32
общий
Какой паскаль? Какие операции над дробями должны поддерживаться?
Неизвестный
07.09.2011, 17:50
общий
Turbo Pascal
Сумма, разность, умножение, деление.
Ну если можно еще тогда сокращение и возведение в степень, хотя думаю первого достаточно будет)) учитель не уточнял какие именно надо..
Неизвестный
07.09.2011, 21:26
общий
это ответ
Здравствуйте, Посетитель - 372181!

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

Сам модуль (см. приложение) должен иметь имя "fraction.pas".

Тест для модуля:
Код:
uses
crt, fraction;
var
a, b, c: frac;

begin
clrscr;
a.p := 2;
a.q := 5;

b.p := 1;
b.q := 3;

add (a, b, c);
writeln ('add: ', c.p, '/', c.q);

dec(a, b, c);
writeln ('dec: ', c.p, '/', c.q);

mult(a, b, c);
writeln ('mult: ', c.p, '/', c.q);

division(a, b, c);
writeln ('division: ', c.p, '/', c.q);

power(b, 3, c);
writeln ('power: ', c.p, '/', c.q);

writeln('done. press any key...');
readkey;
end.


Приложение:
unit fraction;
interface
type
natur = 1..high(longint);
frac = record
p : longint; {числитель дроби}
q : natur {знаменатель дроби}
end;

procedure reduce(var a: frac);
procedure add(a, b: frac; var c: frac);
procedure dec(a, b: frac; var c: frac);
procedure mult(a, b: frac; var c: frac);
procedure division(a, b: frac; var c: frac);
procedure power(a: frac; n : natur; var c: frac);

{раздел реализации модуля}
implementation

{нахождение наибольшего общего делителя (нод) двух чисел - вспомогательная функция}
function nod(a, b: natur): natur;
begin
while (a <> b) do
if (a > b)
then
if (a mod b <> 0)
then
a := (a mod b)
else
a := b
else
if (b mod a <> 0)
then
b := (b mod a)
else
b := a;
nod := a
end;

procedure reduce; {сокращение дроби}
var m, n : natur;
begin
if (a.p <> 0)
then begin
if (a.p < 0)
then
m := abs(a.p)
else
m := a.p; {совмещение типов, т.к. a.p - longint}
n := nod(m, a.q);
a.p := a.p div n;
a.q := a.q div n
end
end;

procedure add; {сумма дробей}
begin
c.q := (a.q * b.q) div nod(a.q, b.q);
c.p := a.p * c.q div a.q + b.p * c.q div b.q;
reduce(c)
end;

procedure dec; {разность дробей}
begin
c.q := (a.q * b.q) div nod(a.q, b.q);
c.p := a.p * c.q div a.q - b.p * c.q div b.q;
reduce(c)
end;

procedure mult; {умножение дробей}
begin
c.q := a.q * b.q;
c.p := a.p * b.p;
reduce(c)
end;

procedure division; {деление дробей}
begin
c.q := a.q * b.p;
c.p := a.p * b.q;
reduce(c)
end;

procedure power; {возведение в степень}
var i : natur;
begin
c.q := 1;
c.p := 1;
reduce(a);
for i := 1 to n do
mult(a, c, c)
end;

{раздел инициализации модуля}
begin
end.
4
давно
Профессионал
304622
583
08.09.2011, 17:28
общий
Для настоящей крутизны можно было ещё ввод/вывод в строковом виде сделать. Вроде '7/15'. Было бы красиво.
Неизвестный
08.09.2011, 19:21
общий
08.09.2011, 19:21
Адресаты:
Цитата: Сергей Бендер
Для настоящей крутизны можно было ещё ввод/вывод в строковом виде сделать. Вроде '7/15'. Было бы красиво.

Проектирование и рефакторинг требуют времени. Для столь недолговечного проекта как текущее задание достаточно было и копипаста :).
Опять же нужно оставить место для творчества и автору вопроса.
давно
Мастер-Эксперт
425
4118
09.09.2011, 10:45
общий
это ответ
Здравствуйте, Посетитель - 372181!

Обычно со сложными типами данных проще работать, когда они представлены как объекты (или классы). Если Вы объекты ещё не изучали, то мой пример Вам просто как информация к размышлению.
Модуль для работы с дробями:
Код:
{Дробь, как объект}

Unit fractions;

interface

Uses Objects;

Type
TFraction = object
numerator : longint; //Числитель
denominator: longint; //Знаменатель
constructor Init(num, denom: longint); //Конструктор дроби
function sum(Other: TFraction): TFraction; //Суммирование
function difference(Other: TFraction): TFraction; //Вычитание
function multiplication(Other: TFraction): TFraction; //Умножение
function division(Other: TFraction): TFraction; //Деление
function LCD(Other: TFraction): longint; //Общий знаменатель
procedure Show; //Выводит дробь на экран
end;
PFraction = ^TFraction;

implementation

constructor TFraction.Init(num, denom: longint);
Begin
numerator:=num;
denominator:=denom;
End;

//Суммирование
function TFraction.sum(Other: TFraction): TFraction;
Var
local: TFraction;
k, k1, k2: longint;
Begin
//Если знаменатели равны
If denominator=Other.denominator Then
Begin
//То просто складываем числители
local.numerator:=numerator+Other.numerator;
//А знаменатель остался неизменным
local.denominator:=denominator;
End
Else
//А если не ровны
Begin
//Находим общий знаменатель
k:=LCD(Other);
//И вычисляем поправочные коэффициенты к первой дроби
k1:=k div denominator;
//И ко второй дроби
k2:=k div Other.denominator;
//Теперь складываем числители, умноженные на поправочный коэффициент
local.numerator:=numerator*k1+Other.numerator*k2;
//А знаменатель у суммы будет найденый ранее общий знаменатель
local.denominator:=k;
End;
sum:=local;
End;

//Вычитание
function TFraction.difference(Other: TFraction): TFraction;
Var
local: TFraction;
k, k1, k2: longint;
Begin
If denominator=Other.denominator Then
Begin
local.numerator:=numerator-Other.numerator;
local.denominator:=denominator;
End
Else
Begin
k:=LCD(Other);
k1:=k div denominator;
k2:=k div Other.denominator;
local.numerator:=numerator*k1-Other.numerator*k2;
local.denominator:=k;
End;
difference:=local;


End;

//Умножение
function TFraction.multiplication(Other: TFraction): TFraction;
Var
local: TFraction;
Begin
local.numerator:=numerator*other.numerator;
local.denominator:=denominator*other.denominator;
multiplication:=local;
End;

//Деление
function TFraction.division(Other: TFraction): TFraction;
Var
local: TFraction;
Begin
local.numerator:=numerator*other.denominator;
local.denominator:=denominator*other.numerator;
division:=local;
End;

//Общий знаменатель
function TFraction.LCD(Other: TFraction): longint;
Begin
If Other.denominator<>denominator Then
LCD:=Other.denominator*denominator
Else
LCD:=denominator;
End;

//Выводит дробь на экран
procedure TFraction.Show;
Begin
Write(numerator,'/',denominator);
End;

end.

Пример использования модуля:
Код:
{Пример работы с дробями-объектами}
Program example;
Uses Fractions;

Var
d1, d2, d3: TFraction;

Begin
d1.numerator:=5;
d1.denominator:=3;
d2.numerator:=1;
d2.denominator:=3;

//Сложение
d3:=d1.sum(d2);
WriteLn('Сложение дробей:');
d1.Show;
Write(' + ');
d2.Show;
Write(' = ');
d3.Show;
WriteLn;
WriteLn;

//Вычитание
d3:=d1.difference(d2);
WriteLn('Вычитание дробей:');
d1.Show;
Write(' - ');
d2.Show;
Write(' = ');
d3.Show;
WriteLn;
WriteLn;

//Умножение
d3:=d1.multiplication(d2);
WriteLn('Умножение дробей:');
d1.Show;
Write(' * ');
d2.Show;
Write(' = ');
d3.Show;
WriteLn;
WriteLn;

//Деление
d3:=d1.division(d2);
WriteLn('Деление дробей:');
d1.Show;
Write(' : ');
d2.Show;
Write(' = ');
d3.Show;
WriteLn;
WriteLn;

End.
5
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
давно
Профессионал
304622
583
09.09.2011, 12:02
общий
Опять же нужно оставить место для творчества и автору вопроса.


Аминь!
Неизвестный
09.09.2011, 14:46
общий
Адресаты:
спасибо)) обязательно гляну, вот только начали изучать объекты
Неизвестный
09.09.2011, 14:49
общий
да, спасибо конечно за копию из книги, у меня это есть..
она говорит надо еще программу сделать, может поможите?? буду очень благодарен
Неизвестный
09.09.2011, 15:26
общий
Цитата: 372181
да, спасибо конечно за копию из книги, у меня это есть..
Простите, не понял о какой копии и книге идет речь
Цитата: 372181
она говорит надо еще программу сделать, может поможите?? буду очень благодарен
Кто такая она? Помочь - оно, конечно, можно, в меру моих возможностей. Давайте определяться с постановкой задачи.
давно
Мастер-Эксперт
425
4118
09.09.2011, 15:28
общий
Только учтите, что и в моём ответе и в ответе эксперта Andrew Kovalchuk отсутствует целая часть дроби, т.е. нельзя задать дробь вида 2 1/2, поэтому такую дробь надо задавать как 3/2.
Кроме того, в моём ответе использован самый простейший алгоритм приведения к общему знаменателю и отсутствует упрощение дроби.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
Неизвестный
09.09.2011, 17:23
общий
Коллеги, давайте не будем придумывать себе работу :)
Автор вопроса просил
модуль работы с обыкновенными дробями.

Обыкновенная дробь - это запись рационального числа в виде [$177$](p/q).
И правильная (abs(p) < abs(q)), и неправильная (abs(p) > abs(q)) дроби являются обыкновенными.
Дробь, записанная в виде целого числа и правильной дроби, называется смешанной дробью и понимается как сумма этого числа и дроби (проще говоря, не строго соответствует понятию дроби обыкновенной).
PS: главное - вовремя остановиться :)
Неизвестный
10.09.2011, 13:08
общий
10.09.2011, 13:09
Книга: "Основы программирования" Автор: Семакин, Шестаков.
Начиная со стр.148 по стр. 151 как раз все это и есть, что вы мне и скинулы в приложении...
"Она" - я имел в виду своего учителя!
Неизвестный
10.09.2011, 14:31
общий
Цитата: 372181
Книга: "Основы программирования" Автор: Семакин, Шестаков.
Начиная со стр.148 по стр. 151 как раз все это и есть, что вы мне и скинулы в приложении...

Чем же вас не удовлетворило имевшееся в книге решение? Ведь оно уже было у вас в руках!
К слову, книгу эту я в глаза не видел до вашего о ней упоминания - специально нашел и скачал. Да согласен, решение одно и то же.
Но чего вы ожидали задавая вопрос в теме? Что кто-то из отвечающих придумает новые правила для операций над дробями?
Предлагаю коллегам оценить степень корректности предоставленного решения поставленной задаче.
PS: вам знакомо понятие "повторное использование кода"?
Неизвестный
11.09.2011, 14:13
общий
Да, номер 372181, Вы зря обижаете эксперта. Почему "2" поставили.. Вы сможете это разумно объяснить?
В ответе дается правильное решение поставленной задачи. Если Вы считате, что нет, то надо было вопрос точнее формулировать, или, хотя бы, запятые ставить ( я не говорю уже о стиле)
Форма ответа