logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Pascal] Jak napisać kalkulator ułamków z procedurami w Pascalu?

Jehoel 16 Cze 2009 20:32 9004 6
REKLAMA
  • #1 6664941
    Jehoel
    Poziom 2  
    Posty: 4
    Mam zrobić program w Pascalu: Napisz program, który oblicza sumę, różnicę, iloczyn i iloraz ułamków zwykłych i przedstawia wynik w postaci ułamka nieskracalnego. Poszczególne działania powinny realizować oddzielne procedury.
    Kombinowałem sam ale nie mam już nerwów. Pomóżcie.




    program mojprogr;
    uses crt;
    var liczn1,liczn2,mian1,mian2,liczn,mian,dziel:Longint;
    znak: char;
    
    procedure dodawanie(liczn1,liczn2,mian1,mian2,liczn,mian:Longint);
    begin
         if mian1=mian2 then mian:=mian1
          else
         if mian1<>mian2 then mian:=mian1*mian2;
         readln;
         liczn:=liczn1+liczn2;
         readln;
         end;
         procedure odejmowanie(liczn1,liczn2,mian1,mian2,liczn,mian:Longint);
         begin
          if mian1=mian2 then mian:=mian1
         else
         if mian1<>mian2 then mian:=mian1*mian2;
         liczn:=liczn1-liczn2;
         end;
         procedure mnozenie(liczn1,liczn2,mian1,mian2,liczn,mian:Longint);
         begin
         liczn:=liczn1*liczn2;
         mian:=mian1*mian2;
         end;
         procedure dzielenie(liczn1,liczn2,mian1,mian2,liczn,mian:Longint);
         begin
         liczn:=liczn1*mian2;
         mian:=mian2*liczn1;
         end;
      begin
       writeln('Wybierz dzialanie');
           writeln(' 1   suma');
           writeln(' 2   roznica');
           writeln(' 3   iloczyn');
           writeln(' 4   iloraz');
           writeln;
           write('Wybierz ');
           read(znak);
           writeln;
    
               writeln('Podaj liczn1:> ');
               readln(liczn1);
         writeln('Podaj mian2:> ');
         readln(mian1);
         writeln('Podaj liczn2:> ');
         readln(liczn2);
         writeln('Podaj mian2:> ');
         readln(mian2);
          case Znak of
           '1':
          begin
          dodawanie(liczn1,liczn2,mian1,mian2,liczn,mian);
           end;
           '2':
           begin
           odejmowanie(liczn1,liczn2,mian1,mian2,liczn,mian);
           end;
           '3':
           begin
           mnozenie(liczn1,liczn2,mian1,mian2,liczn,mian);
           end;
           '4':
           begin
           dzielenie(liczn1,liczn2,mian1,mian2,liczn,mian);
           end;
           end;
           read(liczn);
           write(liczn);
           read(mian);
           write(mian);
           end.


    Proszę używać znaczników [code] - dodałem.
    Regulamin, p. 11. - temat poprawiłem.
    [Dr.Vee]
  • REKLAMA
  • Pomocny post
    #2 6668130
    wrych
    Poziom 20  
    Posty: 279
    Pomógł: 37
    Ocena: 22
    Ta procedura będzie poprawna

    procedure mnozenie(liczn1,liczn2,mian1,mian2,liczn,mian:Longint); 
    begin 
    liczn:=liczn1*liczn2; 
    mian:=mian1*mian2; 
    end;


    po wykonaniu zmiany
    
    procedure mnozenie(liczn1,liczn2,mian1,mian2: Longint; var liczn,mian:Longint); 
    begin 
    liczn:=liczn1*liczn2; 
    mian:=mian1*mian2; 
    end;


    i wtedy po wykonaniu procedury wynik znajdzie się w zmiennych: liczn, mian.
    Podobnie zrób z pozostałymi procedurami i popraw w nich błędy -
    np. w dzieleniu:
    liczn:=liczn1*mian2;  mian:=mian1*liczn2; 
    .
    Dodawanie i odejmowanie zawiera więcej błędów!

    Co do skracania, to poszukaj funkcji NWD, oblicz podzielnik := NWD(licz, mian) i wykonaj dzielenia: licznik := licznik / podzielnik; mianownik := mianownik / podzielnik; i będzie OK.
  • REKLAMA
  • #3 6669173
    Jehoel
    Poziom 2  
    Posty: 4
    Już sobie poradziłem teraz kombinuje tylko z tym skróceniem ułamka i coś nic mi nie wychodzi, ale jak z tym poradziłem to i reszta pójdzie dobrze. Tzn i tak to chaotycznie u mnie wygląda i zapewne za dużo wręcz napisałem, ale jest po sesji w wolnym czasie będę dalej tworzył.

    Dodano po 3 [minuty]:

    Teraz wygląda to tak. Nie korzystałem z Twoich poprawek tylko sam pokombinowałem. Teraz tylko te skracanie jakby mógł ktoś pomóc i może jakieś porady jak to uporządkować tzn. (co wywalić, co zostawić, co przerobić itd.)



    program mojprogr;
    uses crt;
    var liczn1,liczn2,mian1,mian2,liczn,mian:Longint;
    znak: char;
    
    procedure dodawanie;
    begin
         write ('Podaj liczn1: ');
         readln (liczn1);
         write ('Podaj mian1: ');
         readln(mian1);
         write ('Podaj liczn2: ');
         readln (liczn2);
         write ('Podaj mian2: ');
         readln (mian2);
    
                if mian1<>mian2 then mian:=mian1*mian2;
                liczn:=(liczn1*mian2)+(liczn2*mian1);
                if mian1=mian2 then mian:=mian1;
                liczn:=liczn1+liczn2;
         writeln (liczn);
         writeln ('---');
         writeln (mian);
    end;
    
    procedure odejmowanie;
    begin
         write ('Podaj liczn1: ');
         readln (liczn1);
         write ('Podaj mian1: ');
         readln(mian1);
         write ('Podaj liczn2: ');
         readln (liczn2);
         write ('Podaj mian2: ');
         readln (mian2);
    
                if mian1<>mian2 then mian:=mian1*mian2;
                liczn:=(liczn1*mian2)-(liczn2*mian1);
                if mian1=mian2 then mian:=mian1;
                liczn:=liczn1-liczn2;
         writeln (liczn);
         writeln ('---');
         writeln (mian);
     end;
    procedure mnozenie;
    begin
         write ('Podaj liczn1: ');
         readln (liczn1);
         write ('Podaj mian1: ');
         readln(mian1);
         write ('Podaj liczn2: ');
         readln (liczn2);
         write ('Podaj mian2: ');
         readln (mian2);
                liczn:=liczn1*liczn2;
                mian:=mian1*mian2;
         writeln (liczn);
         writeln ('---');
         writeln (mian);
    end;
    procedure dzielenie;
    begin
         write ('Podaj liczn1: ');
         readln (liczn1);
         write ('Podaj mian1: ');
         readln(mian1);
         write ('Podaj liczn2: ');
         readln (liczn2);
         write ('Podaj mian2: ');
         readln (mian2);
                liczn:=liczn1*mian2;
                mian:=mian2*liczn1;
         writeln (liczn);
         writeln ('---');
         writeln (mian);
    end;
    begin
      writeln('Wybierz dzialanie');
           writeln(' +   suma');
           writeln(' -   roznica');
           writeln(' *   iloczyn');
           writeln(' /   iloraz');
           writeln;
           write('Wybierz ');
           read(znak);
           case Znak of
           '+':
          begin
          dodawanie;
           end;
           '-':
           begin
           odejmowanie;
           end;
           '*':
           begin
           mnozenie;
           end;
           '/':
           begin
           dzielenie;
           end;
           end;
            read (liczn);
           read (mian);
           end. 


    Dodano po 21 [minuty]:

    No dobra mam tą funkcję na Największy wspólny dzielnik z algorytmu Euklidesa:

    function nwd(liczn, mian: Integer): Integer;
    var
      tmp: Integer;
    begin
      repeat
        tmp := liczn mod mian;
        liczn := mian;
        mian := tmp;
      until mian = 0;
      nwd := liczn;
    end;


    i teraz niech ktoś mi powie jak ją użyć, gdzie wpisać itd. bo ja już ciemny jestem. Wszystko mi się sypie w głowie.

    Jeszcze raz - znaczniki [code].
  • Pomocny post
    #4 6669345
    wrych
    Poziom 20  
    Posty: 279
    Pomógł: 37
    Ocena: 22
    Teraz Twoje procedury działają na zmiennych globalnych (trochę to mało eleganckie) i operacje podstawienia zmieniają wartości zmiennych liczn i mian. W poprzednim przypadku były tworzone lokalne zmienne w procedurze i wyniki "nie wychodziły na zewnątrz". Moje poprawki miały na celu przekazywanie danych przez wartość a wyniki były by umieszczane w zmiennych (przez referencje).
    Co do skracania, to może to wyglądać tak:
    1) Deklarujesz funkcję:
    function nwd(a, b: LongInt): Longint;
    var
      tmp: Integer;
    begin
      repeat
        tmp := a mod b;
        a := b;
        b := tmp;
      until b = 0;
      nwd := a;
    end;
    

    2) Obliczasz:
    dzielnik := nwd(licz, mian);
    licz := licz div dzielnik;
    mian := mian div dzielnik;
    

    i po problemie...
  • REKLAMA
  • #5 6669681
    Jehoel
    Poziom 2  
    Posty: 4
    Dzięki za pomoc
  • REKLAMA
  • #6 6677319
    Jehoel
    Poziom 2  
    Posty: 4
    Mój problem polega na tym, że nie wiem jak to przerobić.Jestem już głupi jak cholera, naprawdę nie wiem co mam zrobić, ani co mnie podkusiło ten temat wybrać.
    Proszę jeszcze raz o tą samą pomoc.

    program dodawanie;
    uses crt;
    var liczn1,liczn2,mian1,mian2,liczn,mian,dzieln:Longint;
    
    begin
         write ('Podaj liczn1: ');
         readln (liczn1);
         write ('Podaj mian1: ');
         readln(mian1);
         write ('Podaj liczn2: ');
         readln (liczn2);
         write ('Podaj mian2: ');
         readln (mian2);
    
                if mian1<>mian2 then mian:=mian1*mian2;
                liczn:=(liczn1*mian2)+(liczn2*mian1);
                if mian1=mian2 then mian:=mian1;
                liczn:=liczn1+liczn2;
                
    while liczn<>mian do
    
        if liczn>mian then
         liczn:=liczn-mian
          else
           mian:=mian-liczn;
           writeln('NWD TO: ',liczn);
           dzieln :=
    liczn := liczn div dzieln;
    mian := mian div dzieln;
         writeln (liczn);
         writeln ('---');
         writeln (mian);
    end.

    Chodzi o to że tutaj:
       writeln('NWD TO: ',liczn);

    wyświetla mi ten największy wspólni dzielnik, ale co wpisać tutaj
     dziel:=      

    żeby mi go wczytało i działało dalej, bo naprawdę nie wiem co na to poradzić. Jeśli możecie pomóżcie/podpowiedzcie.
  • #7 6681207
    wrych
    Poziom 20  
    Posty: 279
    Pomógł: 37
    Ocena: 22
    Ten fragment kodu:
    while liczn<>mian do
    
        if liczn>mian then
         liczn:=liczn-mian
          else
           mian:=mian-liczn;
           writeln('NWD TO: ',liczn);

    poprawnie liczy NWD dla liczb "liczn" i "mian", ale niestety ich wartość ulega zmianie, a będą one potrzebne do wyświetlenia wyniku.
    Należało by zatem wartości tych zmiennych zapamiętać i po obliczeniu NWD odtworzyć.
    Lepszym rozwiązaniem będzie zrobienie funkcji, tak jak Ci to wcześniej sugerowałem.
    Masz ponadto błędnie napisane wcześniej obliczenia - zamiast:
    if mian1<>mian2 then mian:=mian1*mian2;
                    liczn:=(liczn1*mian2)+(liczn2*mian1);
                if mian1=mian2 then mian:=mian1;
                    liczn:=liczn1+liczn2;
    

    powinno być
    if mian1<>mian2 then
                  begin
                    mian:=mian1*mian2;
                    liczn:=(liczn1*mian2)+(liczn2*mian1);
                  end;
                if mian1=mian2 then
                  begin
                    mian:=mian1;
                    liczn:=liczn1+liczn2;
                  end;

    Poczytaj jakiś podstawowy kurs Pascala (instrukcje warunkowe, instrukcja złożona).
    Oto cały kod z przeróbkami:
    
    program dodawanie; 
    uses crt; 
    var liczn1,liczn2,mian1,mian2,liczn,mian,dzieln:Longint; 
    function NWD(liczn, mian: Longint): Longint;
    begin
     while liczn<>mian do
    
        if liczn>mian then
         liczn:=liczn-mian
          else
           mian:=mian-liczn;
           {writeln('NWD TO: ',liczn);}
           nwd := liczn    ;
    end;
    begin
         write ('Podaj liczn1: ');
         readln (liczn1);
         write ('Podaj mian1: ');
         readln(mian1);
         write ('Podaj liczn2: ');
         readln (liczn2);
         write ('Podaj mian2: ');
         readln (mian2);
    
                if mian1<>mian2 then
                  begin
                    mian:=mian1*mian2;
                    liczn:=(liczn1*mian2)+(liczn2*mian1);
                  end;
                if mian1=mian2 then
                  begin
                    mian:=mian1;
                    liczn:=liczn1+liczn2;
                  end;
    
         dzieln := nwd(liczn, mian);
         liczn := liczn div dzieln;
         mian := mian div dzieln;
         writeln (liczn); 
         writeln ('---'); 
         writeln (mian);
         readln
    end.

Podsumowanie tematu

✨ Dyskusja dotyczy napisania programu w Pascalu realizującego operacje na ułamkach zwykłych: sumę, różnicę, iloczyn i iloraz, z wynikami w postaci nieskracalnych ułamków. Kluczowym problemem było prawidłowe przekazywanie parametrów do procedur oraz implementacja funkcji skracającej ułamek poprzez obliczenie największego wspólnego dzielnika (NWD). Sugerowano zmianę procedur tak, aby wyniki były zwracane przez zmienne przekazywane przez referencję (var), a nie przez wartość, co umożliwiało poprawne aktualizowanie zmiennych globalnych. Wskazano także na błędy w obliczeniach dodawania i odejmowania ułamków, które wymagały poprawnego uwzględnienia wspólnego mianownika. Proponowano implementację funkcji nwd(a,b) wykorzystującej algorytm Euklidesa do obliczenia NWD, a następnie dzielenie licznika i mianownika przez ten dzielnik w celu uzyskania ułamka nieskracalnego. Zwrócono uwagę na konieczność zachowania oryginalnych wartości licznika i mianownika podczas obliczania NWD, aby nie utracić danych potrzebnych do wyświetlenia wyniku. Dyskusja zawierała fragmenty kodu Pascal z poprawkami i sugestiami dotyczącymi struktury programu i organizacji procedur.
Podsumowanie wygenerowane przez AI na podstawie treści dyskusji.
REKLAMA