C++-Programmierung/ Brüche/ Zusammenfassung


Hier finden Sie noch einmal das komplette Programm, inklusive der Ausgabe eines Durchlaufs.

Nuvola-inspired-terminal.svg
#include <iostream>

unsigned int ggT(unsigned int a, unsigned int b){
    if(b == 0)
        return a;
    else return ggT(b, a % b);
}

unsigned int kgV(unsigned int a, unsigned int b){
    return a/ggT(a,b) * b;
}

class Bruch{
public:
    Bruch(int zaehler = 0, unsigned int nenner = 1); // Konstruktoren
    Bruch(double wert);                              // dieser ist nicht perfekt

    int          zaehler()const {return zaehler_;}  // Gibt Zähler zurück
    unsigned int nenner()const  {return nenner_;}   // Gibt Nenner zurück

    Bruch& operator+=(Bruch const &lvalue);
    Bruch& operator-=(Bruch const &lvalue);
    Bruch& operator*=(Bruch const &lvalue);
    Bruch& operator/=(Bruch const &lvalue);

    // Umwandlung in Gleitkommatypen
    operator float()      {return static_cast<float>(zaehler_)/nenner_;}
    operator double()     {return static_cast<double>(zaehler_)/nenner_;}
    operator long double(){return static_cast<long double>(zaehler_)/nenner_;}

private:
    void kuerzen();                                  // kürzt weitestmöglich

    int          zaehler_;
    unsigned int nenner_;
};


// Diese Methoden erstellen eine temporäre Kopie (lhs) ihres Objekts, führen
// die Rechenoperation auf ihr aus und geben sie dann zurück
inline Bruch const operator+(Bruch lhs, Bruch const &rhs){ return lhs += rhs; }
inline Bruch const operator-(Bruch lhs, Bruch const &rhs){ return lhs -= rhs; }
inline Bruch const operator*(Bruch lhs, Bruch const &rhs){ return lhs *= rhs; }
inline Bruch const operator/(Bruch lhs, Bruch const &rhs){ return lhs /= rhs; }


Bruch::Bruch(int zaehler, unsigned int nenner):
    zaehler_(zaehler),
    nenner_(nenner){
    kuerzen();
}

Bruch::Bruch(double wert):
    zaehler_(static_cast<int>(wert*1000000.0+0.5)),
    nenner_(1000000){
    kuerzen();
}

void Bruch::kuerzen(){
    unsigned int tmp = ggT(zaehler_, nenner_); // ggT in tmp speichern
    zaehler_ /= tmp;                            // Zähler durch ggT teilen
    nenner_  /= tmp;                            // Nenner durch ggT teilen
}

Bruch& Bruch::operator+=(Bruch const &lvalue){
    unsigned int tmp = kgV(nenner_, lvalue.nenner_);
    zaehler_ = zaehler_ * (tmp / nenner_) + lvalue.zaehler_ * (tmp / lvalue.nenner_);
    nenner_  = tmp;
    return *this; // Referenz auf sich selbst zurückgeben
}

Bruch& Bruch::operator-=(Bruch const &lvalue){
    unsigned int tmp = kgV(nenner_, lvalue.nenner_);
    zaehler_ = zaehler_ * (tmp / nenner_) - lvalue.zaehler_ * (tmp / lvalue.nenner_);
    nenner_  = tmp;
    return *this; // Referenz auf sich selbst zurückgeben
}

Bruch& Bruch::operator*=(Bruch const &lvalue){
    zaehler_ *= lvalue.zaehler_;
    nenner_  *= lvalue.nenner_;
    kuerzen();    // Bruch wieder kürzen
    return *this; // Referenz auf sich selbst zurückgeben
}

Bruch& Bruch::operator/=(Bruch const &lvalue){
    zaehler_ *= lvalue.nenner_;
    nenner_  *= lvalue.zaehler_;
    kuerzen();    // Bruch wieder kürzen
    return *this; // Referenz auf sich selbst zurückgeben
}

std::ostream& operator<<(std::ostream &os, Bruch const &bruch){
    return os << '(' << bruch.zaehler() << '/' << bruch.nenner() << ')';
}

std::istream& operator>>(std::istream &is, Bruch &bruch){
    char tmp;
    int zaehler, nenner;
    is >> tmp;
    if(tmp=='('){
        is >> zaehler;
        is >> tmp;
        if(tmp=='/'){
            is >> nenner;
            is >> tmp;
            if(tmp==')'){
                bruch=Bruch(zaehler, nenner); // Bruch erzeugen und Wert übernehmen
                return is;
            }
        }
    }
    is.setstate(std::ios_base::failbit);      // Fehlerstatus setzen
    return is;
}

int main(){
    Bruch zahl1, zahl2, ergebnis;                      // Variablen für Zahlen vom Typ Bruch
    char rechenzeichen;                                // Variable fürs Rechenzeichen

    std::cout << "Geben Sie eine Rechenaufgabe ein: "; // Eingabeaufforderung ausgeben
    std::cin >> zahl1 >> rechenzeichen >> zahl2;       // Aufgabe einlesen

    switch(rechenzeichen){                             // Wert von rechenzeichen ermitteln
        case '+': ergebnis = zahl1+zahl2; break;       // entsprechend dem
        case '-': ergebnis = zahl1-zahl2; break;       // Rechenzeichen
        case '*': ergebnis = zahl1*zahl2; break;       // das Ergebnis
        case '/': ergebnis = zahl1/zahl2; break;       // berechnen
        // Fehlerausgabe und Programm beenden, falls falsches Rechenzeichen
        default: std::cout << "unbekanntes Rechenzeichen...\n"; return 1;
    }

    // Aufgabe noch mal komplett ausgeben
    std::cout << zahl1 << ' ' << rechenzeichen << ' ' << zahl2 << " = " << ergebnis << '\n';
    std::cout << static_cast<double>(zahl1) << ' '     // Ausgabe als
              << rechenzeichen << ' '                  // Gleitkommawerte
              << static_cast<double>(zahl2) << " = "
              << static_cast<double>(ergebnis) << '\n';
}
Crystal Clear app kscreensaver.svg
Ausgabe:
Geben Sie eine Rechenaufgabe ein: <Eingabe>(1/5)-(3/4)</Eingabe>
(1/5) - (3/4) = (-11/20)
0.2 - 0.75 = -0.55