C++ rechnen mit rationalen Zahlen



  • hallo Leute,
    ich hab ne Programm, das mit rationalen Zahlenrechnet.
    meine header datei lautet

    // ratio.h
    // Klasse für rationale Zahlen
    #ifndef ratio_h
    #define ratio_h
    
    class rational
    {
          public:
                 rational()
                 : zaehler(1), nenner(1)
                 {}                     //inline
                 rational(long);        //Typumwandlungskonstroktor
    
                 // Abfrage inline
                 long Zaehler () const {return zaehler;}
                 long Nenner () const {return nenner;}
    
                void add(rational a, rational b);
                void sub(rational a, rational b);
                void mult(rational a, rational b);
                void div(rational z, rational n);
    
                void definiere(long zaehler, long nenner);
                void eingabe();
                void ausgabe() const;
                void kehrwert();
                void kuerzen();
    
          private:
            long zaehler, nenner;
        };
        #endif
    

    Bibliothek:

    / ratio.cpp 
    #include"ratio.h"
    #include<iostream>
    #include<assert.h>
    
    rational::rational(long ganz)       // Typumwandlungskonstrukstor
    {
        zaehler = ganz;
        nenner = 1;
                            }
    
    void rational::add(rational a, rational b)
    {
         zaehler = a,zaehler*b.nenner + b.zaehler*a.nenner;
         nenner  = a.nenner*b.nenner;
         kuerzen();
         }
    :
     ...
    ....
    
    void rational::eingabe()
    {
         /* cerr wird gewaehlt, damit die Abfragen auch dann auf dem Bildschirm erscheinen,
          wenn die Standardausgabe in eine Datei zur Dokumentation geleitet wird.*/
     std::cerr <<"Geben Sie den Zaehler ein :";
     std::cin >> zaehler;
     std::cerr <<"Geben Sie den Nenner ein :";
     std::cin >> nenner;
     assert(nenner!=0);
    }
    
    void rational::ausgabe() const
    {
         std::cout << zaehler << "/" << nenner << std::endl;
    }
    
    void rational::kehrwert()
    {
         long temp = zaehler;
         zaehler = nenner;
         nenner = temp;
         assert(nenner !=0);
    }
    
    long ggt(long x, long y)
    {
         long teiler, zaehler, nenner;
         int sign = 1;
         if (zaehler < 0) { sign = -sign; zaehler = -zaehler;}
         if (nenner   <0) { sign = -sign; nenner = - nenner;}
         long reiler=ggt(zaehler,nenner);
         zaehler = sign*zaehler/teiler;
         nenner = nenner/teiler;
    }
    

    und mein programm mit funktionen lautet:

    #include"ratio.h"
    #include<iostream>
    
    // alle 4 Operationen fuer a und b
    void druckeTestfall(rational a, rational b)
    {
         rational erg;
         std::cout << "a = " ; a.ausgabe();
         std::cout << "b = "; b.ausgabe();
         erg.add(a,b);
         std::cout << "+  : "; erg.ausgabe();
         erg.sub(a,b);
         std::cout << "-  : "; erg.ausgabe();
         erg.mult(a,b);
         std::cout << "*  : "; erg.ausgabe();
         erg.div(a,b);
         std::cout << "/  : "; erg.ausgabe();
         std::cout<<std::endl;
    }
    
    int main()
    {
        rational a,b;
        std::cout << "Test der Eingabe\n";
        std::cout << "a:\n"; a.eingabe();
        std::cout << "b:\n"; b.eingabe();
        druckeTestfall(a,b);
    
        std::cout <<"\n Test mit verschiedenen Vorzeichen\n";
        a.definiere(3,7);    b.definiere(6,13);
        druckeTestfall(a,b);
        a.definiere(3,-7);
        druckeTestfall(a,b);
    
        //....
    
        std::cout <<"Test mit Nullwerten\n";
        a.definiere(0,7);   b.definiere(6,13);
        druckeTestfall(a,b);
        a.definiere(3,0);
        druckeTestfall(a,b);
    
        //...
    
        std::cout <<"\n Test mit gemischten Datentypen\n";
        a.definiere(2301,77777);
        druckeTestfall(a,17);
        druckeTestfall(17,a);
    
        //...
    }
    

    kann jemand bitte mir helfen das Programm zu beenden, denn ich bekomme fehlermeldungen beim compilieren.



  • > kann jemand bitte mir helfen das Programm zu beenden,

    Bei entsprechender Eigeninitiative gerne. :xmas1:

    > denn ich bekomme fehlermeldungen beim compilieren.

    Wie nett, dass du uns diese auch zeigst.



  • Nachtrag:
    Das letzte Code-stück ist nicht so wichtig. Und das zwite ist natürlich auch nicht die Bibliothek.

    Das Problem besteht unter anderem darin, dass der Compiler in ratio.cpp meint, dass zaehler, nenner und teiler nich deklariert wurde. Aber das habe ich doch in der header-datei gemacht, oder?
    Und dann meint der Compiler das er am anfang von ratio.cpp nicht von rational auf long springen kann.

    Ich hoffe auf eure Hilfe.

    MfG

    expert


  • Mod

    In deinem Code sind lauter "....". Das funktioniert natürlich nicht.



  • Die ... sind nur um zu zeigen dass ich da was weggelassen habe vor dem posten... die hab ich natürlich nicht im Programmm.^^



  • Toll. Wieso schreibst du nicht endlich die Fehlermeldung? 😡



  • Das Problem besteht unter anderem darin, dass der Compiler in ratio.cpp meint, dass zaehler, nenner und teiler nich deklariert wurde. Aber das habe ich doch in der header-datei gemacht, oder?
    Und dann meint der Compiler das er am anfang von ratio.cpp nicht von rational auf long springen kann.

    ich habe oben doch beschrieben....



  • Hab ich doch, oder? Dritter Beitrag. Naja etwas genauer:

    In member function void rational::add(rational, rational)': cannot convert \rational' to `long int' in assignment

    In function `long int ggt(long int, long int)': `zaehler' undeclared (first use this function)

    `nenner' undeclared (first use this function)

    `teiler' undeclared (first use this function)

    und mir ist noch aufgefallen:
    [Build Error] [ratio.o] Error 1

    Hoffe das ist ok.


  • Mod

    expert schrieb:

    Naja etwas genauer:

    Was den Unterschied zwischen unbrauchbar und nützlich ausmacht. Interpretieren ist für Gedichte da, der Computer möchte es etwas präziser haben.

    In member function void rational::add(rational, rational)': cannot convert \rational' to `long int' in assignment

    Schreibfehler: Komma statt Punkt geschrieben.



  • Nein, wie blöd... danke wegen des Punkts^^.



  • Hat denn einer ne Idee woher die anderen Probleme kommen könnten, oder besser wie sie beseitigt werden können?



  • Ja. Aber warum versuchst du nicht wenigstens, aus den Fehlermeldungen schlau zu werden? Genauer als "... undeclared" kann man nicht deklarierte Variablen ja wirklich nicht mehr beschreiben.


  • Mod

    ggt ist bei dir keine Memberfunktion von rational und kennt daher auch nicht dessen Membervariablen.



  • Vielen Danke, Leute!
    Habt mir sehr geholfen!

    MfG

    expert



  • Hallo,
    bin auf ein neues Problem gestossen.
    Und zwar soll ich die den Additionsoperator und natürlich die anderen arithmetischen Operatoren (von denen hab ich den Code nicht gepostet) überladen.
    Kann mir jemand von euch anhand des Additionsoperators zeigen, wie das gehen könnte und wie ich das entsprechend einbaue.

    Habe schon folgenden Ansatz:

    rational operator+(rational a, rational b)
    {
             rational t;
             t.zaehler = a.zaehler*b.nenner + b.zaehler*a.nenner;
             t.nenner  = a.nenner*b.nenner;
             t.kuerzen();
             return t;
    }
    
    rational operator+(rational a, rational b)
    {
             return b+a;
    }
    

    Jedoch komm ich da nicht weiter.



  • Was soll der zweite operator bezwecken und was soll "ich komme nicht weiter" heißen? Ist es so schwer eine Frage vernünftig zu stellen?


  • Mod

    Was heißt nicht weiterkommen? So wie ich das sehe bist du schon fertig:

    rational operator+(rational a, rational b)
    {
             rational t;
             t.zaehler = a.zaehler*b.nenner + b.zaehler*a.nenner;
             t.nenner  = a.nenner*b.nenner;
             t.kuerzen();
             return t;
    }
    

    (Wobei man noch erwähnen sollte, dass man den + Operator meistens vom += Operator ableitet, aber das ist eine andere Geschichte)



  • Wie genau bekomme ich das denn nun angewendet? Mein Zaehler und mein Nenner sind ja privat. Und wenn das gelöst is reicht es dann, wenn ich einfach wieder mein Testprogramm benutze?

    ratio.h: In function `rational operator+(rational, rational)':

    ratio.h:30: error: long int rational::zaehler' is private ratio.cpp:92: error: within this context ratio.h:30: error:long int rational::zaehler' is private
    ratio.cpp:92: error: within this context
    ratio.h:30: error: long int rational::nenner' is private ratio.cpp:92: error: within this context ratio.h:30: error:long int rational::zaehler' is private
    ratio.cpp:92: error: within this context
    ratio.h:30: error: long int rational::nenner' is private ratio.cpp:92: error: within this context ratio.h:30: error:long int rational::nenner' is private
    ratio.cpp:93: error: within this context
    ratio.h:30: error: long int rational::nenner' is private ratio.cpp:93: error: within this context ratio.h:30: error:long int rational::nenner' is private
    ratio.cpp:93: error: within this context


  • Mod

    Mach den Operator zum friend!



  • Achso... ich dachte ich bräuchte das nur, wenn ich keinen Typumwandlungskonstruktor habe.
    Müsste dann so aussehen:

    friend rational operator+(long, rational);
    friend rational operator+(rational, long);
    

    ,oder?

    Das setz ich dann direkt über die rational operator?


  • Mod

    expert schrieb:

    Achso... ich dachte ich bräuchte das nur, wenn ich keinen Typumwandlungskonstruktor habe.
    Müsste dann so aussehen:

    friend rational operator+(long, rational);
    friend rational operator+(rational, long);
    

    ,oder?

    Der Operator in deinem Beispiel hat aber die Singatur

    rational operator+(rational, rational);
    

    Das setz ich dann direkt über die rational operator?

    Nein, friend Deklarationen gehören in die Klasse.


Anmelden zum Antworten