Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ приведение дроби к несократимому виду

Автор: marwell 3.01.2010 22:04

нужно написать программу приведения дроби к несократимому виду.


var i,a,b,p,q:integer;
function NOD(a:integer; b:integer):integer;
begin
while(a<>0) and (b<>0) do
if a>=b then a:=a mod b
else b:=b mod a;
NOD:=a+b;
end;
function NOK (A: integer; B: integer): integer;
begin
NOK := a * b div NOD (a, b);
end;
procedure Socr(a,b:integer; var p,q:integer);
begin
if a=b then begin
p:=1;
q:=1;
end
else if NOD (a, b)<>1 then
begin
NOD (a, b);
p:=a/NOD(a, b); {вот в этой строчке выдает ошибку}
q:=b/NOD(a, b);
end;
begin
Writeln('введите числитель');
Readln(a);
Writeln('введите знаменатель');
Readln(b);
Socr(a,b);
Writeln(p,'/',q);
readln;
end.


признаюсь, в процедурах и функциях я разбираюсь не очень хорошо((((
при прогоне выдает ошибку [Error] Project2.dpr(28): Incompatible types: 'Integer' and 'Extended'
не подскажите, в чем проблема?

Автор: volvo 3.01.2010 22:16

Цитата
не подскажите, в чем проблема?
Деление ВСЕГДА возвращает результат вещественного типа. Если тебе нужно делить нацело - используй Div, или приводи частное к целому типу через Trunc.

Кстати, у тебя нарушена структура программы (одного End-а не хватает). А не видно этого - потому что исходник не отформатирован как положено.

Автор: marwell 3.01.2010 22:22

Цитата(volvo @ 3.01.2010 18:16) *

Деление ВСЕГДА возвращает результат вещественного типа. Если тебе нужно делить нацело - используй Div, или приводи частное к целому типу через Trunc.

ааа, вот оно что! спасибо

Добавлено через 2 мин.
Цитата(volvo @ 3.01.2010 18:16) *

Деление ВСЕГДА возвращает результат вещественного типа. Если тебе нужно делить нацело - используй Div, или приводи частное к целому типу через Trunc.

блин, опять ошибка((

var i,a,b,p,q:integer;
function NOD(a:integer; b:integer):integer;
begin
while(a<>0) and (b<>0) do
if a>=b then a:=a mod b
else b:=b mod a;
NOD:=a+b;
end;
function NOK (A: integer; B: integer): integer;
begin
NOK := a * b div NOD (a, b);
end;
procedure Socr(a,b:integer; var p,q:integer);
begin
if a=b then begin
p:=1;
q:=1;
end
else if NOD (a, b)<>1 then
begin
NOD (a, b);
p:=a div NOD(a, b);
q:=b div NOD(a, b);
end;
begin
Writeln('введите числитель');
Readln(a);
Writeln('введите знаменатель');
Readln(b);
Socr(a,b); {тут ошибка [Error] Project2.dpr(36): Not enough actual parameters}
Writeln(p,'/',q);
readln;
end.


что неправильно?

Автор: volvo 3.01.2010 22:35

Цитата
что неправильно?
Тебе компилятор сказал, что неправильно.

Ты сколько параметров передаешь в процедуру? А сколько она ждет?
Кстати:
Цитата
       else if NOD (a, b)<>1 then
begin
NOD (a, b); // <--- Вот эта строка что здесь делает ???
p:=a div NOD(a, b);
q:=b div NOD(a, b);
end;

Автор: marwell 3.01.2010 22:41

Цитата(volvo @ 3.01.2010 18:35) *

Тебе компилятор сказал, что неправильно.

Ты сколько параметров передаешь в процедуру? А сколько она ждет?
Кстати:

аааааа, ошибся

var i,a,b,p,q:integer;
function NOD(a:integer; b:integer):integer;
begin
while(a<>0) and (b<>0) do
if a>=b then a:=a mod b
else b:=b mod a;
NOD:=a+b;
end;
function NOK (A: integer; B: integer): integer;
begin
NOK := a * b div NOD (a, b);
end;
procedure Socr(a,b:integer; var p,q:integer);
begin
if a=b then begin
p:=1;
q:=1;
end
else if NOD (a, b)<>1 then
begin
p:=a div NOD(a, b);
q:=b div NOD(a, b);
end
else Writeln ('введенная дробь уже несократима');
end;
begin
Writeln('введите числитель');
Readln(a);
Writeln('введите знаменатель');
Readln(b);
Socr(a,b,p,q);
Writeln(p,'/',q);
readln;
end.


Автор: marwell 3.01.2010 23:04

а как с помощью этой процедуры привести дробь 1+1/2+1/3+1/4+...+1/20 к несократимому виду?

Автор: volvo 3.01.2010 23:20

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

Автор: marwell 3.01.2010 23:51

Цитата(volvo @ 3.01.2010 19:20) *

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


procedure add_ratio(var res: ratio; curr: ratio);
var new_denom: longint;
begin
div_ratio(curr);

new_denom := NOK(res.denom, curr.denom);
res.num :=
res.num * (new_denom div res.denom) +
curr.num * (new_denom div curr.denom);
res.denom := new_denom;

div_ratio(res);
end;

var
curr: ratio;
const
{ Изначально результат = 0, т.е. 0/1 }
res: ratio = (num:0; denom:1);

begin
writeln('Дроби (0 в числителе для окончания подсчета)');
repeat
write('Числитель: '); readln(curr.num);
if curr.num <> 0 then begin
write('Знаменатель: '); readln(curr.denom);
if curr.denom = 0 then
repeat
writeln('Деление на 0 недопустимо!');
write('Знаменатель: '); readln(curr.denom);
until curr.denom <> 0;

add_ratio(res, curr);
end;
until curr.num = 0;

writeln('Результат = ', res.num, '/', res.denom);
end.


этот подходит?
Delphi ругается на тип ratio dry.gif

Автор: marwell 4.01.2010 1:26

Цитата(volvo @ 3.01.2010 19:20) *

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

посмотри пожалуйста, так правильно?

var a_1,a_2,b_1,b_2,p,q:integer;
function NOD(a:integer; b:integer):integer;
begin
while(a<>0) and (b<>0) do
if a>=b then a:=a mod b
else b:=b mod a;
NOD:=a+b;
end;
function NOK (A: integer; B: integer): integer;
begin
NOK := a * b div NOD (a, b);
end;
procedure Socr(a,b:integer; var p,q:integer);
begin
if a=b then begin
p:=1;
q:=1;
end
else if NOD (a, b)<>1 then
begin
p:=a div NOD(a, b);
q:=b div NOD(a, b);
end
else Writeln ('введенная дробь несократима');
end;
begin
a_1:=1;
a_2:=1;
b_1:=1;
for b_2:=2 to 20 do
begin
a_1:=(NOK(b_1, b_2) div b_1)*a_1;
a_1:=a_1+((NOK(b_1, b_2) div b_2)*a_2);
b_1:=NOK(b_1, b_2);
end;
writeln (a_1,'/',b_1);
Socr(a_1,b_1,p,q);
Writeln (p,'/',q);
readln;
end.


Автор: marwell 4.01.2010 17:08

ну посмотрите кто-нибудь, please!!!