Ideen zur "Benutzerfreundlichkeit" von eigener Klasse gesucht
-
Hallo,
ich programmiere schon seit einer ganzen Weile an einer Klasse, die mit sehr großen Zahlen rechnen kann. Im Vorhinein möchte ich anmerken, dass ich noch nicht viel (praxis-) Erfahrung mit C++ oder allgemein Programmiersprachen habe und meine Zahlen Klasse als reines Übungsprojekt für mich zu verstehen ist (es kommt also nicht in erster Line auf Performance- oder Plattformunabhängigkeit usw an).
Meine Klasse stellt die Zahlen als short Arrays dar. Ein Array für den Teil "vor" dem Komma und ein weiteres short Array für die Zahlen "nach" dem Komma. Gerade bin ich dabei, die Division zu implementieren.
Dabei habe ich ein "konzeptionelles" Problem: Bei der Division von 1 und 3 gibt es ja im Prinzip unendlich viele Nachkommastellen. Das "Nachkomma" Array kann (theoretisch) ca. 4mrd Elemente aufnehmen(größe von size_t). Würde das Ergebnis von 1/3 wirklich in einem Objekt meiner Klasse auf die 4 Mrd. Nachkommastelle berechnet werden, gäbe es bei jeder weiteren Rechnung natürlich extreme Performance Einbußungen (einen entsprechend großen Arbeitsspeicher vorrausgesetzt
).
Daher möchte ich es dem Benutzer meiner Klasse ermöglichen, die "Genauigkeit", also die Anzahl der ermittelten Nachkommastellen, selbst anzugeben. Jetzt könnte ich natürlich eine Funktion schreiben, zB obj division(obj1, obj2, genauigkeit). Allerdings möchte ich die Division über den "/" Operator ausführen lassen.Langer Text, kurzer Sinn: Wenn ihr eine Klasse zum Berechnen großer Zahlen mit "variabler" genauigkeit benutzen würdet, wie stellt ihr euch das Bestimmen dieser Genauigkeit vor? Eine globale Variable, die diesen Wert festlegt? Oder eine #define bzw Präprozessor Anweisung (mit denen ich mich garnicht auskenne^^)?
Header.h: unsigned int Genauigkeit=1000; class BigNum { };main.cpp: int main() { Genauigkeit=2000; //Hier stellt Benutzer Genauigkeit ein //das wirkt aber irgendwie nicht "professionell", habe ich das Gefühl Bignum Obj=1/3; }Ich hoffe ihr versteht, was ich meine

-
Mach die Genauigkeit-Variable im Header zu einem const int und speichere den Config-Teil des Headers separat als "config.hpp" Dort kann der User dann die Genauigkeit für die Berechnungen global einstellen.
Alternativ wäre es noch denkbar, dass jede BigNum-Instanz einen Genauigkeits-Wert mit sich trägt. Operator / hast du ja bestimmt als freie Funktion definiert. Dieser Operator müsste jetzt von beiden Operanden den größeren Genauigkeitswert auswählen und das Ergebnis auf diese länge Runden.
Natürlich hätten die Klassen bei der zweiten Methode einen Default-Wert, den kannst du wieder aus einer globalen Config beziehen. Aber wenn der User jetzt eine bestimmte Berechnung präziser haben will, kann er sowas schreiben wie:
BigNum op1 = 1; BigNum op2 = 3; op2.resolution = 1000; // Max 1000 Nachkommastellen BigNum erg = op1 / op2; assert(erg.resolution == 1000); // True...das wäre dann ein ähnlicher Mechanismus wie bei float / double. Es wird zu genaueren Typen hochgecastet. Würde ich gut finden!
-
Na wenn es variabel sein soll, dann macht ein konstantes define natürlich noch weniger Sinn als eine Globale. Das sollte doch eher eine Eigenschaft deiner Klasse und durch den Benutzer festzulegen sein.
-
Eine globale Variable, die diesen Wert festlegt? Oder eine #define bzw Präprozessor Anweisung (mit denen ich mich garnicht auskenne^^)?
Beide Varianten: auf keinen Fall.
a) Per Template-Parameter (bignum<100> i = 4;)
b) Per Ctor-Parameter (bignum i = bignum(4, 100);)
c) Dynamisch, ohne feste Grenze (bignum i = 4;) - geht aber nur, wenn man sich auf Ganzzahlen beschränktJe nachdem was für deine Anwendung mehr Sinn macht.
IMO ist die beste Variante (c).
Wenn man Kommastellen braucht, dann würde ich (a) vorziehen.EDIT: hab die dummen smileys deaktiviert...
-
Lieber b). Wenn es ein Template-Parameter ist, kannst du es zur Laufzeit nicht mehr ändern und es wird auch bei Funktionsparametern u.ä. zusätzlich umständlich.
-
und es wird auch bei Funktionsparametern u.ä. zusätzlich umständlich
Dafuer gibts typedefs, die koennen das bissi entschaerfen ...
Die entscheidung ob Variante a, oder Eine der Varianten b oder c sollte definitiv von der Verwendung bzw den Vorgaben abhaengig sein.
Soll/Kann der Programmierer die Genauigkeit schon waehrend des programmierens, also vorm kompilieren eindeutig festlegen, wuerd ich definitiv Variante A vorziehen. Weil, man kann besser optimieren, das ergebniss wird um laengen performanter, damit steigt die wiederverwendbarkeit, zumindest solange das Kriterium eingehalten wird.
Ist die Genauigkeit zur Kompilezeit ned fest, klar, scheidet nen template auf die genauigkeit aus. Ob das Ding seine genauigkeit selber bestimmt, bzw vom programmierer vorgegeben wird, kann nur der verwender eindeutig bestimmen.
Version b wird performanter zu implementieren sein, weil man ner Instanz nachtraeglich die genauigkeit sicher ned aendern kann, wenn doch, dann mit den entsprechenden konsequenzen.
bei ner automatischen bestimmung muesste man sicher noch viel mehr Infos auf vorrat halten, bzw intern auf ner hoeheren genauigkeit rechnen, um bei unguenstigen Kombinationen keinen Muell zu liefern.
Ist sein Zahlenmodell so gut, bzw so mutzlich in seinem umfeld, und sollen so viele wie möglich es verwenden, auch die mit anspruch an die performance, wird er sicher alle 3 varianten implementieren ^^
Ciao ...
-
Die richtige Lösung ist natürlich intern 1/3 zu speichern und nur, wenn explizit gefordert eine gerundete Dezimalzahldarstellung zu generieren und dort wird natürlich auch die Anzahl der Stellen mitangegeben.
-
So gehts richtig schrieb:
Die richtige Lösung ist natürlich intern 1/3 zu speichern und nur, wenn explizit gefordert eine gerundete Dezimalzahldarstellung zu generieren und dort wird natürlich auch die Anzahl der Stellen mitangegeben.
Das ist grober Unfug.