Rational type (C++)
-
Hallo zusammen,
ich habe eine Klasse Rational geschrieben (inspiriert durch eines meiner Bücher), die das Rechnen mit Brüchen ermöglicht:
https://github.com/Raincode/Rational
Wenn jemand die paar Zeilen Code anschauen möchte und mir dazu ein paar Tips gibt, hätte ich nichts dagegen, will ja dazulernen.Mag sein, dass es in boost oder anderen Bibliotheken schon so etwas gibt (sehr wahrscheinlich), aber das ist A bestimmt komplizierter und B ging es mir hier eher um den Übungs-/Lerneffekt
Habe vor das dann auch in einen Taschenrechner einzubauen, dazu brauch ich aber erstmal einen fertigen Taschenrechner^^
LG
-
- double nach Rational: brocot-stern-baum testen und falls doof, eine zeile kommentieren, daß abgelehnt.
- dito mit binary gcd.
- normalize macht kürzen UND vorzeichenkorrektur und wird als so fette Funktion viel zu oft benutzt (z.B. +/* nur kürzen braucht).
- to_double ist doppelt.
- gcd könnte man auf unsigned beschränken.
-
Überläufe werden nicht vernünftig behandelt; nicht einmal dann, wenn das (normalisierte) Ergebnis exakt darstellbar ist.
-
Hallo,
vielen herzlichen Dank für eure Rückmeldungen.
Werde auf jeden Fall eure Tipps versuchen umzusetzen.
edit: Habs aufs Wesentliche reduziert.
-
Nochmals hallöchen,
ich bin wirklich gegen Doppelposts, aber ich hab das Gefühl das geht an allen vorbei, wenn ich einfach nur meinen vorherigen Beitrag editiere.
Ich stehe vor einer Designfrage, die mich wirklich ins Grübeln bringt.
Es geht darum, ob meine Klasse Rational Zugang zu Zähler und Nenner bieten soll.
Ich weiß, dass boost::rational sowas macht. Ich finde es auch sinnvoll, da ich so die ganzen 'friend' Funktionen aus der Klasse rausnehmen kann.
Nachteil wäre halt, dass die Kapselung schlechter ist. Wehe dem, der überall ein seinem Programm sowas macht:int x = myRational.numerator(); // use x
und ich entscheide mich irgendwann, dass ich 'long long' statt 'int' möchte. Alles natürlich rein hypothetisch.
Also was meint ihr, Verbergen von Implementatierungsdetails, oder Flexibilität? Oder so ähnlich...
Ich hab mir auch schon überlegt einfach irgendein typedef zu verwenden (glaub boost::rational machts auch so ähnlich), aber dann hab ich ja immernoch das Probem (eigentlich):
Rational::int_type x = myRational.numerator(); // ... int foo = x * bar; // hhhmmmmmm
Falls das an dieser Stelle doch unpassend sein sollte, kann ich auch einen Thread im C++-Forum aufmachen (wär ja nicht das erste Mal).
-
HarteWare schrieb:
int x = myRational.numerator(); // use x
und ich entscheide mich irgendwann, dass ich 'long long' statt 'int' möchte. Alles natürlich rein hypothetisch.
Dann wird der Wert truncated. Aber da der Code vom Anwender sowieso nur mit dem Wertebereich von int klar kommt, ist das nicht weiter schlimm. Weil er wird dann schon dafür gesorgt haben, dass es keinen int-Overflow vorher gab.
Ich hab mir auch schon überlegt einfach irgendein typedef zu verwenden (glaub boost::rational machts auch so ähnlich), aber dann hab ich ja immernoch das Probem (eigentlich):
Rational::int_type x = myRational.numerator(); // ... int foo = x * bar; // hhhmmmmmm
Dann muss man da halt auch das Typedef nehmen.
C++11 auto löst übrigens alle diese Probleme.
-
Ok, dann werde ich also sowas machen:
class Rational { public: typedef int int_type; // ...
Vielen Dank.