C++-Programmierung/ Brüche/ Zusammenfassung

Aus Wikibooks
Zur Navigation springen Zur Suche springen


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

Nuvola-inspired-terminal.svg
  1 #include <iostream>
  2 
  3 unsigned int ggT(unsigned int a, unsigned int b){
  4     if(b == 0)
  5         return a;
  6     else return ggT(b, a % b);
  7 }
  8 
  9 unsigned int kgV(unsigned int a, unsigned int b){
 10     return a/ggT(a,b) * b;
 11 }
 12 
 13 class Bruch{
 14 public:
 15     Bruch(int zaehler = 0, unsigned int nenner = 1); // Konstruktoren
 16     Bruch(double wert);                              // dieser ist nicht perfekt
 17 
 18     int          zaehler()const {return zaehler_;}  // Gibt Zähler zurück
 19     unsigned int nenner()const  {return nenner_;}   // Gibt Nenner zurück
 20 
 21     Bruch& operator+=(Bruch const &lvalue);
 22     Bruch& operator-=(Bruch const &lvalue);
 23     Bruch& operator*=(Bruch const &lvalue);
 24     Bruch& operator/=(Bruch const &lvalue);
 25 
 26     // Umwandlung in Gleitkommatypen
 27     operator float()      {return static_cast<float>(zaehler_)/nenner_;}
 28     operator double()     {return static_cast<double>(zaehler_)/nenner_;}
 29     operator long double(){return static_cast<long double>(zaehler_)/nenner_;}
 30 
 31 private:
 32     void kuerzen();                                  // kürzt weitestmöglich
 33 
 34     int          zaehler_;
 35     unsigned int nenner_;
 36 };
 37 
 38 
 39 // Diese Methoden erstellen eine temporäre Kopie (lhs) ihres Objekts, führen
 40 // die Rechenoperation auf ihr aus und geben sie dann zurück
 41 inline Bruch const operator+(Bruch lhs, Bruch const &rhs){ return lhs += rhs; }
 42 inline Bruch const operator-(Bruch lhs, Bruch const &rhs){ return lhs -= rhs; }
 43 inline Bruch const operator*(Bruch lhs, Bruch const &rhs){ return lhs *= rhs; }
 44 inline Bruch const operator/(Bruch lhs, Bruch const &rhs){ return lhs /= rhs; }
 45 
 46 
 47 Bruch::Bruch(int zaehler, unsigned int nenner):
 48     zaehler_(zaehler),
 49     nenner_(nenner){
 50     kuerzen();
 51 }
 52 
 53 Bruch::Bruch(double wert):
 54     zaehler_(static_cast<int>(wert*1000000.0+0.5)),
 55     nenner_(1000000){
 56     kuerzen();
 57 }
 58 
 59 void Bruch::kuerzen(){
 60     unsigned int tmp = ggT(zaehler_, nenner_); // ggT in tmp speichern
 61     zaehler_ /= tmp;                            // Zähler durch ggT teilen
 62     nenner_  /= tmp;                            // Nenner durch ggT teilen
 63 }
 64 
 65 Bruch& Bruch::operator+=(Bruch const &lvalue){
 66     unsigned int tmp = kgV(nenner_, lvalue.nenner_);
 67     zaehler_ = zaehler_ * (tmp / nenner_) + lvalue.zaehler_ * (tmp / lvalue.nenner_);
 68     nenner_  = tmp;
 69     return *this; // Referenz auf sich selbst zurückgeben
 70 }
 71 
 72 Bruch& Bruch::operator-=(Bruch const &lvalue){
 73     unsigned int tmp = kgV(nenner_, lvalue.nenner_);
 74     zaehler_ = zaehler_ * (tmp / nenner_) - lvalue.zaehler_ * (tmp / lvalue.nenner_);
 75     nenner_  = tmp;
 76     return *this; // Referenz auf sich selbst zurückgeben
 77 }
 78 
 79 Bruch& Bruch::operator*=(Bruch const &lvalue){
 80     zaehler_ *= lvalue.zaehler_;
 81     nenner_  *= lvalue.nenner_;
 82     kuerzen();    // Bruch wieder kürzen
 83     return *this; // Referenz auf sich selbst zurückgeben
 84 }
 85 
 86 Bruch& Bruch::operator/=(Bruch const &lvalue){
 87     zaehler_ *= lvalue.nenner_;
 88     nenner_  *= lvalue.zaehler_;
 89     kuerzen();    // Bruch wieder kürzen
 90     return *this; // Referenz auf sich selbst zurückgeben
 91 }
 92 
 93 std::ostream& operator<<(std::ostream &os, Bruch const &bruch){
 94     return os << '(' << bruch.zaehler() << '/' << bruch.nenner() << ')';
 95 }
 96 
 97 std::istream& operator>>(std::istream &is, Bruch &bruch){
 98     char tmp;
 99     int zaehler, nenner;
100     is >> tmp;
101     if(tmp=='('){
102         is >> zaehler;
103         is >> tmp;
104         if(tmp=='/'){
105             is >> nenner;
106             is >> tmp;
107             if(tmp==')'){
108                 bruch=Bruch(zaehler, nenner); // Bruch erzeugen und Wert übernehmen
109                 return is;
110             }
111         }
112     }
113     is.setstate(std::ios_base::failbit);      // Fehlerstatus setzen
114     return is;
115 }
116 
117 int main(){
118     Bruch zahl1, zahl2, ergebnis;                      // Variablen für Zahlen vom Typ Bruch
119     char rechenzeichen;                                // Variable fürs Rechenzeichen
120 
121     std::cout << "Geben Sie eine Rechenaufgabe ein: "; // Eingabeaufforderung ausgeben
122     std::cin >> zahl1 >> rechenzeichen >> zahl2;       // Aufgabe einlesen
123 
124     switch(rechenzeichen){                             // Wert von rechenzeichen ermitteln
125         case '+': ergebnis = zahl1+zahl2; break;       // entsprechend dem
126         case '-': ergebnis = zahl1-zahl2; break;       // Rechenzeichen
127         case '*': ergebnis = zahl1*zahl2; break;       // das Ergebnis
128         case '/': ergebnis = zahl1/zahl2; break;       // berechnen
129         // Fehlerausgabe und Programm beenden, falls falsches Rechenzeichen
130         default: std::cout << "unbekanntes Rechenzeichen...\n"; return 1;
131     }
132 
133     // Aufgabe noch mal komplett ausgeben
134     std::cout << zahl1 << ' ' << rechenzeichen << ' ' << zahl2 << " = " << ergebnis << '\n';
135     std::cout << static_cast<double>(zahl1) << ' '     // Ausgabe als
136               << rechenzeichen << ' '                  // Gleitkommawerte
137               << static_cast<double>(zahl2) << " = "
138               << static_cast<double>(ergebnis) << '\n';
139 }
Crystal Clear app kscreensaver.svg
Ausgabe:
1 Geben Sie eine Rechenaufgabe ein: <Eingabe>(1/5)-(3/4)</Eingabe>
2 (1/5) - (3/4) = (-11/20)
3 0.2 - 0.75 = -0.55