** Аритметични операции за обикновени дроби

Направете функции, които извършват аритметичните операции събиране, изваждане, умножение и целочислено деление между две обикновени дроби, подадени като параметри. В главната програма с помощта на тези функции пресметнете изразите:

  1. 2/3 + 3/4 =
  2. 4/5 – 3/6 =
  3. 1/6 * 25/4 =
  4. 25/4 : 2/ =

По желание: Да се добавят и функции, които проверяват дали дробта е правилна или неправилна, за представянето на неправилните дроби като смесени числа и за съкращаване на числителя и знаменателя доколкото е възможно.

Публикувано в 10в, 11а, 11в с етикети . Постоянна връзка.

7 Responses to ** Аритметични операции за обикновени дроби

  1. kaloyan каза:

    „4. 25/4 : 2/колко =“ направил съм го с 2/1. За целочисленото делене не съм сигурен дали така трябва да се направи :D

    function sabirane(a,b:real):real;
    begin
      result:=a+b;
    end;
    
    function izvajdane(a,b:real):real;
    begin
      result:=a-b;
    end;
    
    function umnojenie(a,b:real):real;
    begin
      result:=a*b;
    end;
    
    function delene(a,b:real):real;
    begin
      result:=a/b;
    end;
    
    BEGIN
      writeln(sabirane(2/3,3/4):0:2);
      writeln(izvajdane(4/5,3/6):0:2);
      writeln(umnojenie(1/6,25/4):0:2);
      writeln(delene(25/4,2/1):0:0);
    
    readln;
    END.           
    • Данаил каза:

      Калояне, целта на тази задача е да се направят функции, които извършват операциите с обикновени дроби, като ги запазват като обикновени (с числител и знаменател), а не да ги превръщат в десетични. Например умножението би трябвало да бъде така: ако a3/b3 = a1/b1 * a2/b2, то a3=a1*a2 и b3=b1*b2 Тоест за да намерим числителя и знаменателя на резултата, умножаваме числителите и знаменателите на двете дроби.

  2. kaloyan каза:
    procedure sakrashtavane(var a3,b3:integer; var ch:real);//Процедура за съкращаване на дробите
    var i:integer;
    begin
    if a3>b3 then ch:=a3/b3
      else
    if a3<=b3 then
      for i:=b3 downto 1 do
        if a3 mod i = 0 then
          if b3 mod i = 0 then begin
            a3:=a3 div i;
            b3:=b3 div i;
          end;
    end;
    //Събиране
    procedure sabirane(out a3,b3:integer; out ch:real);
    var a1,b1,a2,b2,i:integer;
    begin
    a1:=2;
    b1:=3;
    a2:=3;
    b2:=4;
    //Пресмятаме като дроб
    a3:=((b2*a1)+(b1*a2));
    b3:=b1*b2;
    sakrashtavane(a3,b3,ch);//Извъкваме процедурата за съкращаване
    end;
    //Изваждане
    procedure izvajdane(out a3,b3:integer; out ch:real);
    var a1,b1,a2,b2,i:integer;
    begin
    a1:=4;
    b1:=5;
    a2:=3;
    b2:=6;
    //Пресмятаме като дроб
    a3:=((b2*a1)-(b1*a2));
    b3:=b1*b2;
    sakrashtavane(a3,b3,ch);//Извъкваме процедурата за съкращаван
    end;
    //Умножение
    procedure umnojenie(out a3,b3:integer; out ch:real);
    var a1,b1,a2,b2,i:integer;
    begin
    a1:=1;
    b1:=6;
    a2:=25;
    b2:=4;
    //Пресмятаме като дроб
    a3:=a1*a2;
    b3:=b1*b2;
    sakrashtavane(a3,b3,ch);//Извъкваме процедурата за съкращаван
    end;
    //Делене
    procedure delene(out a3,b3:integer; out ch:real);
    var a1,b1,a2,b2,i:integer;
    begin
    a1:=25;
    b1:=4;
    a2:=2;
    b2:=1;
    //Пресмятаме като дроб
    a3:=a1*b2;
    b3:=b1*a2;
    sakrashtavane(a3,b3,ch);//Извъкваме процедурата за съкращаван
    end;
    
    VAR a3,b3:integer;
        ch:real;
    BEGIN
    //Събиране
    sabirane(a3,b3,ch);
      if a3<=b3 then writeln(a3,'/',b3)
        else
      if a3>b3 then writeln(ch:0:2);
    //Изваждане
    izvajdane(a3,b3,ch);
      if a3<=b3 then writeln(a3,'/',b3)
        else
      if a3>b3 then writeln(ch:0:2);
    //Умножение
    umnojenie(a3,b3,ch);
      if a3<=b3 then writeln(a3,'/',b3)
        else
      if a3>b3 then writeln(ch:0:2);
    //Делене
    delene(a3,b3,ch);
      if a3<=b3 then writeln(a3,'/',b3)
        else
      if a3>b3 then writeln(ch:0:2);
    
    readln;
    END.
  3. kaloyan каза:
    //Проверка дали дробта е правилна или неправилна
    function proverka(a3,b3:integer):boolean;
    begin
      if a3<=b3 then result:=true//Правилна
        else
      if a3>b3 then result:=false//Неправилна
    end;
    //Процедура за съкращаване
    procedure sakrashtavane(var a3,b3:integer);//Процедура за съкращаване на дробите
    var i,max:integer;
    begin
    if a3>b3 then max:=a3
    else max:=b3;
      for i:=2 to max do
        if a3 mod i = 0 then
          if b3 mod i = 0 then begin
            a3:=a3 div i;
            b3:=b3 div i;
          end;
    end;
    //Превръщане в смесено число
    procedure smeseno(const a3,b3:integer; var a,b,c:integer);
    begin
    if not(proverka(a3,b3)) then
      a:=a3 div b3;//Цяла част
      b:=a3-(a*b3);//Числител
      c:=b3;//Знаменател
    end;
    //Събиране
    procedure sabirane(const a1,b1,a2,b2:integer; out a3,b3,a,b,c:integer);
    var i:integer;
    begin
    a3:=((b2*a1)+(b1*a2));
    b3:=b1*b2;
    sakrashtavane(a3,b3);//Извъкваме процедурата за съкращаване
    if not(proverka(a3,b3)) then smeseno(a3,b3,a,b,c);
    end;
    //Изваждане
    procedure izvajdane(const a1,b1,a2,b2:integer; out a3,b3,a,b,c:integer);
    var i:integer;
    begin
    a3:=((b2*a1)-(b1*a2));
    b3:=b1*b2;
    sakrashtavane(a3,b3);//Извъкваме процедурата за съкращаванe
    if not(proverka(a3,b3)) then smeseno(a3,b3,a,b,c);
    end;
    //Умножение
    procedure umnojenie(const a1,b1,a2,b2:integer; out a3,b3,a,b,c:integer);
    var i:integer;
    begin
    a3:=a1*a2;
    b3:=b1*b2;
    sakrashtavane(a3,b3);//Извъкваме процедурата за съкращаванe
    if not(proverka(a3,b3)) then smeseno(a3,b3,a,b,c);
    end;
    //Делене
    procedure delene(const a1,b1,a2,b2:integer; out a3,b3,a,b,c:integer);
    var i:integer;
    begin
    a3:=a1*b2;
    b3:=b1*a2;
    sakrashtavane(a3,b3);//Извъкваме процедурата за съкращаванe
    if not(proverka(a3,b3)) then smeseno(a3,b3,a,b,c);
    end;
    
    VAR a1,b1,a2,b2,a3,b3,a,b,c:integer;
    BEGIN
    //Събиране
    sabirane(2,3,3,4,a3,b3,a,b,c);
      if proverka(a3,b3) then writeln(a3,'/',b3)
      else writeln(a,' ',b,'/',c);
    //Изваждане
    izvajdane(4,5,3,6,a3,b3,a,b,c);
      if proverka(a3,b3) then writeln(a3,'/',b3)
      else writeln(a,' ',b,'/',c);
    //Умножение
    umnojenie(1,6,25,4,a3,b3,a,b,c);
      if proverka(a3,b3) then writeln(a3,'/',b3)
      else writeln(a,' ',b,'/',c);
    //Делене
    delene(25,4,2,1,a3,b3,a,b,c);
      if proverka(a3,b3) then writeln(a3,'/',b3)
      else writeln(a,' ',b,'/',c);
    readln;
    END.
    • Данаил каза:

      Браво, голям напредък по задачата! Почти си на финала! Процедурата smeseno обаче не ми харесва – ако дробта е правилна, няма да се запише нищо в параметрите a,b,c. И няма как да се разбере дали там ще има нещо или не, освен да се вика проверка. Тоест тази функция понякога работи, а понякога не. Добрата функция е като инструмент (като тесла или лопата например – винаги работи :-) За мен по-добро решение щеше да бъде ако когато дробта е правилна, за цялата част се връща 0. Тогава и функциите за събиране, изваждане, умножение и деление ще станат по-прости и само с 3 изходящи параметъра. Дори аз бих ги направил с два, за да връщат само числителя и знаменателя на резултата – защо винаги да преобразуват към смесени числа – може това понякога да не е желано (например ако ще продължим със следващи изчисления с дробите, получени като резултат). И накрая бих направил една функция за печат на дроби, която проверява дали дробта е правилна или неправилна и евентуално отпечатва неправилната дроб като смесено число. Така и главната програма ще стане по-проста.

      Има някои прости препоръки, които трябва да се знаят за писане на „добри“ функции:
      1. Една функция прави едно нещо
      2. Една функция винаги връща резултат
      3. Ако има повторения в кода, значи може да се заменят с функция

      И малко обяснение по 1: ако функцията прави много неща, първо тя става сложна като код, има повече вероятност за грешки в нея, от извикването и не може да се разбере коя от всичките си функции изпълнява и, понеже прави какво ли не, вероятно ще се извиква от много места в програмата и при промяна на функцията има по-голям шанс за прецакване на програмата на много места :-) Ако функцията е проста и прави едно нещо, всички изброени по-горе недостатъци се избягват.

  4. kaloyan каза:
    //Проверка дали дробта е правилна или неправилна
    function proverka(a,b:integer):boolean;
    begin
      if a<=b then result:=true//Правилна
        else
      if a>b then result:=false//Неправилна
    end;
    //Процедура за съкращаване
    procedure sakrashtavane(var a,b:integer);
    var i,max:integer;
    begin
    if a>b then max:=a
    else max:=b;
      for i:=max downto 2 do
        if a mod i = 0 then
          if b mod i = 0 then begin
            a:=a div i;
            b:=b div i;
          end;
    end;
    //Превръщане в смесено число
    procedure smeseno(var a,b,c:integer);
    var x,y:integer;
    begin
    if proverka(a,b) then c:=0
      else
    begin
    x:=a;
    y:=b;
      c:=x div y;//Цяла част
      a:=x-(c*y);//Числител
      b:=y;//Знаменател
    end;
    end;
    //Събиране
    procedure sabirane(const a1,b1,a2,b2:integer; out a,b:integer);
    begin
    a:=((b2*a1)+(b1*a2));
    b:=b1*b2;
    sakrashtavane(a,b);
    end;
    //Изваждане
    procedure izvajdane(const a1,b1,a2,b2:integer; out a,b:integer);
    begin
    a:=((b2*a1)-(b1*a2));
    b:=b1*b2;
    sakrashtavane(a,b);
    end;
    //Умножение
    procedure umnojenie(const a1,b1,a2,b2:integer; out a,b:integer);
    begin
    a:=a1*a2;
    b:=b1*b2;
    sakrashtavane(a,b);
    end;
    //Делене
    procedure delene(const a1,b1,a2,b2:integer; out a,b:integer);
    begin
    a:=a1*b2;
    b:=b1*a2;
    sakrashtavane(a,b);
    end;
    //Процедура за превръщане на дробта в смесено число(ако е нужно) и отпечатване
    procedure pechat(a,b,c:integer);
    begin
    smeseno(a,b,c);
    if c<>0 then writeln(c,' ',a,'/',b)
        else writeln(a,'/',b);
    end;
    
    VAR a1,b1,a2,b2,a,b,c:integer;
    BEGIN
    //Събиране
    sabirane(2,3,3,4,a,b);
    pechat(a,b,c);
    //Изваждане
    izvajdane(4,5,3,6,a,b);
    pechat(a,b,c);
    //Умножение
    umnojenie(1,6,25,4,a,b);
    pechat(a,b,c);
    //Делене
    delene(25,4,2,1,a,b);
    pechat(a,b,c);
    
    readln;
    END.
    • Данаил каза:

      Перфектно! Мисля, че вече знаеш малко повече по въпроса каква е ползата от функциите и как да употребяваш ефективно параметрите им :-)

      Ако лятото качваш решения и по задачите от предишни години, при първа възможност ще ги преглеждам и ако имам забележки ще ти пиша. Иначе само ще ги одобрявам. Другият вариант е да решаваш задачи от сайта, който ти казах, или да разгледаш архивите на форума по информатика (регистрирай се там, пиши кой потребител си и ще ти дам пълни права да виждаш всичко и да публикуваш).

Вашият коментар