C++-Programmierung/ Brüche/ Zusammenfassung
Aus Wikibooks
Hier finden Sie noch einmal das komplette Programm, inklusive der Ausgabe eines Durchlaufs.
#include <iostream> // Bindet auch die Datei <ios> ein
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 m_zaehler;} // Gibt Zähler zurück
unsigned int nenner()const {return m_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);
// Diese Methoden erstellen eine Temporäre Kopie ihres Objekts, führen
// die Rechenoperation auf ihr aus und geben sie dann zurück
Bruch operator+(Bruch const &lvalue)const{return Bruch(*this)+=lvalue;}
Bruch operator-(Bruch const &lvalue)const{return Bruch(*this)-=lvalue;}
Bruch operator*(Bruch const &lvalue)const{return Bruch(*this)*=lvalue;}
Bruch operator/(Bruch const &lvalue)const{return Bruch(*this)/=lvalue;}
// Umwandlung in Gleitkommatypen
operator float() {return static_cast<float>(m_zaehler)/m_nenner;}
operator double() {return static_cast<double>(m_zaehler)/m_nenner;}
operator long double(){return static_cast<long double>(m_zaehler)/m_nenner;}
private:
void kuerzen(); // kürzt weitestmöglich
int m_zaehler;
unsigned int m_nenner;
};
Bruch::Bruch(int zaehler, unsigned int nenner):
m_zaehler(zaehler),
m_nenner(nenner){
kuerzen();
}
Bruch::Bruch(double wert):
m_zaehler(static_cast<int>(wert*1000000.0+0.5)),
m_nenner(1000000){
kuerzen();
}
void Bruch::kuerzen(){
unsigned int tmp = ggT(m_zaehler, m_nenner); // ggT in tmp speichern
m_zaehler /= tmp; // Zähler durch ggT teilen
m_nenner /= tmp; // Nenner durch ggT teilen
}
Bruch& Bruch::operator+=(Bruch const &lvalue){
unsigned int tmp = kgV(m_nenner, lvalue.m_nenner);
m_zaehler = m_zaehler * (tmp / m_nenner) + lvalue.m_zaehler * (tmp / lvalue.m_nenner);
m_nenner = tmp;
return *this; // Referenz auf sich selbst zurückgeben
}
Bruch& Bruch::operator-=(Bruch const &lvalue){
unsigned int tmp = kgV(m_nenner, lvalue.m_nenner);
m_zaehler = m_zaehler * (tmp / m_nenner) - lvalue.m_zaehler * (tmp / lvalue.m_nenner);
m_nenner = tmp;
return *this; // Referenz auf sich selbst zurückgeben
}
Bruch& Bruch::operator*=(Bruch const &lvalue){
m_zaehler *= lvalue.m_zaehler;
m_nenner *= lvalue.m_nenner;
kuerzen(); // Bruch wieder kürzen
return *this; // Referenz auf sich selbst zurückgeben
}
Bruch& Bruch::operator/=(Bruch const &lvalue){
m_zaehler *= lvalue.m_nenner;
m_nenner *= lvalue.m_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';
}
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 m_zaehler;} // Gibt Zähler zurück
unsigned int nenner()const {return m_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);
// Diese Methoden erstellen eine Temporäre Kopie ihres Objekts, führen
// die Rechenoperation auf ihr aus und geben sie dann zurück
Bruch operator+(Bruch const &lvalue)const{return Bruch(*this)+=lvalue;}
Bruch operator-(Bruch const &lvalue)const{return Bruch(*this)-=lvalue;}
Bruch operator*(Bruch const &lvalue)const{return Bruch(*this)*=lvalue;}
Bruch operator/(Bruch const &lvalue)const{return Bruch(*this)/=lvalue;}
// Umwandlung in Gleitkommatypen
operator float() {return static_cast<float>(m_zaehler)/m_nenner;}
operator double() {return static_cast<double>(m_zaehler)/m_nenner;}
operator long double(){return static_cast<long double>(m_zaehler)/m_nenner;}
private:
void kuerzen(); // kürzt weitestmöglich
int m_zaehler;
unsigned int m_nenner;
};
Bruch::Bruch(int zaehler, unsigned int nenner):
m_zaehler(zaehler),
m_nenner(nenner){
kuerzen();
}
Bruch::Bruch(double wert):
m_zaehler(static_cast<int>(wert*1000000.0+0.5)),
m_nenner(1000000){
kuerzen();
}
void Bruch::kuerzen(){
unsigned int tmp = ggT(m_zaehler, m_nenner); // ggT in tmp speichern
m_zaehler /= tmp; // Zähler durch ggT teilen
m_nenner /= tmp; // Nenner durch ggT teilen
}
Bruch& Bruch::operator+=(Bruch const &lvalue){
unsigned int tmp = kgV(m_nenner, lvalue.m_nenner);
m_zaehler = m_zaehler * (tmp / m_nenner) + lvalue.m_zaehler * (tmp / lvalue.m_nenner);
m_nenner = tmp;
return *this; // Referenz auf sich selbst zurückgeben
}
Bruch& Bruch::operator-=(Bruch const &lvalue){
unsigned int tmp = kgV(m_nenner, lvalue.m_nenner);
m_zaehler = m_zaehler * (tmp / m_nenner) - lvalue.m_zaehler * (tmp / lvalue.m_nenner);
m_nenner = tmp;
return *this; // Referenz auf sich selbst zurückgeben
}
Bruch& Bruch::operator*=(Bruch const &lvalue){
m_zaehler *= lvalue.m_zaehler;
m_nenner *= lvalue.m_nenner;
kuerzen(); // Bruch wieder kürzen
return *this; // Referenz auf sich selbst zurückgeben
}
Bruch& Bruch::operator/=(Bruch const &lvalue){
m_zaehler *= lvalue.m_nenner;
m_nenner *= lvalue.m_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';
}
Geben Sie eine Rechenaufgabe ein: <Eingabe>(1/5)-(3/4)</Eingabe>
(1/5) - (3/4) = (-11/20)
0.2 - 0.75 = -0.55
(1/5) - (3/4) = (-11/20)
0.2 - 0.75 = -0.55