boost::rational kuerzt nicht
-
Hallo,
ich habe das Problem, dass wen bei ich boost::rational<unsigned> den *= Operator benutze, die Klasse intern die Werte nicht kuerzt da der Numerator immer ungerade ist. So wird der Denominator irgendwann zu groß, und die ganze Klasse setzt alles auf 0 zurück. Gibt es da irgendwelche Tricks das Problem zu beheben, außer z.B. 64-bit Werte zu nehmen?
-
ja, wenn du glaubst, dass es zu groß wird, selbst kürzen. Aber nach jeder Multiplikationen einen ggt zu suchen ist nicht wirklich effizient, deshalb machen die das wohl nicht.
-
@otze: Selber kürzen kann man nicht, boost::rational garantiert jederzeit die gekürzte Darstellung.
Rationals are always stored in fully normalized form (ie, gcd(numerator,denominator) = 1, and the denominator is always positive).
In der bei mir installierten Boost-Library sieht der operator*= so aus:
template <typename IntType> rational<IntType>& rational<IntType>::operator*= (const rational<IntType>& r) { // Protect against self-modification // Bemerkung 1: Hä? Ist das hier nicht unnötigt? // Kostet das nicht vier Kopierkonstruktoren für nichts? IntType r_num = r.num; IntType r_den = r.den; // Avoid overflow and preserve normalization IntType gcd1 = math::gcd(num, r_den); // Bemerkung 2: math::gcd ist so implementiert wie man IntType gcd2 = math::gcd(r_num, den); // es erwarten würde, testet also nicht nur auf Parität. num = (num/gcd1) * (r_num/gcd2); den = (den/gcd2) * (r_den/gcd1); return *this; }RationalerDenker, weshalb meinst du den, dass nicht gekürzt wird?
-
oh ich kannte die Biliothek nicht. ich habs nur daraus geschlossen, dass du gesagt hast, dass er nicht kürzt, weil der Numerator immer ungerade ist. Aber ungerade ist kein Kriterium für ggt(a,b) = 1.
Daraus schließe ich: boost::rational kürzt ->zähler und nenner sind zueinander prim->du brauchst einen größeren Datentyp.