2012-03-30 4 views
5

verwenden? Ich möchte eine BigInt-Klasse implementieren, die wirklich große Zahlen verarbeiten kann. Ich möchte nur Zahlen addieren und multiplizieren, aber die Klasse sollte auch negative Zahlen behandeln.Welche Datenstruktur sollte ich für die BigInt-Klasse

Ich wollte die Zahl als eine Zeichenfolge darstellen, aber es gibt einen großen Overhead mit der Konvertierung von Zeichenfolge in int und zurück zum Hinzufügen. Ich möchte hinzufügen, wie auf der High School, fügen Sie entsprechende Reihenfolge hinzu und wenn das Ergebnis größer als 10 ist, fügen Sie den Übertrag zur nächsten Bestellung hinzu.

Dann dachte ich, dass es besser wäre, es als ein Array von unsigned long long int zu behandeln und das Zeichen durch bool getrennt zu halten. Damit habe ich Angst vor der Größe des int, da der C++ - Standard soweit ich weiß nur den Int < float < doppelt garantiert. Korrigiere mich, wenn ich falsch liege. Wenn ich also eine Nummer erreiche, sollte ich das Array nach vorne bewegen und die Nummer zur nächsten Array-Position hinzufügen.

Gibt es eine geeignete oder bessere Datenstruktur?

+0

Klingt wie eine vernünftige Implementierung für mich. Aber wenn Sie ULONGs verwenden, kann jedes Element im Array einen Wert von 0 bis 2^32-1 anstelle von 0 bis 10 enthalten. Das sollte Ihnen ein paar Bytes sparen. :-) –

+1

Der Standard garantiert nur 'float <= double' (beachte das Gleichheitszeichen) – ipc

+0

Ja, genau das meinte ich. Aber ist 2^32 - 1 das gleiche auf Linux und auf Solaris? Ist die Größe überall garantiert? Mein Punkt ist, dass zum Beispiel MyBigIntClass number = "234567434256547"; , und ich fange an, diese Zeichenkettennummer in meine innere Darstellung in der Klasse zu konvertieren, die lange long int (vielleicht :-)) usigned ist, und nachdem die Zahl 2^32 erreicht hat, bewege ich mich an eine andere Position im Array. Ist es richtig? – user1086004

Antwort

5

Sie möchten also ein dynamisches Array von Ganzzahlen einer bekannten Größe?

Sounds wie vector<uint32_t> sollte für Sie arbeiten.

+0

leider ist STL nicht erlaubt – user1086004

+2

Hausaufgaben? eingebettet? In jedem Fall benötigen Sie etwas wie "Vektor". Glücklicherweise ist es eine einfache Übung, ein grundlegendes "dynamisches Array" nachzubilden." – Joni

2

Wie Sie bereits herausgefunden haben, müssen Sie bestimmte Typen in Ihrer Plattform (oder der Sprache, wenn Sie C++ 11 haben), die eine feste Größe haben. Eine übliche Implementierung einer großen Zahl würde 32-Bit-Ganzzahlen verwenden und sicherstellen, dass nur die unteren 16 Bits gesetzt werden. Dies ermöglicht Ihnen, die Ziffern zu bearbeiten (wobei Ziffer wäre [0..2^16)) und dann normalisieren das Ergebnis durch die Übertragungen zu übernehmen.

+0

Für Addition/Subtraktion kann Carry auf dem Weg durchgeführt werden und Sie brauchen nicht zwei Durchgänge. Für die Multiplikation hängt es vom Algorithmus ab, aber wenn Sie zB Gleitkomma-FFT-Methoden verwenden, brauchen Sie nicht trägt auch (aber es ist besser, 16 Bit "Ziffern" zu verwenden, da Sie Rundungsfehler während der FFT akkumulieren). –

2

Auf einer modernen 64-Bit-x86-Plattform ist es wahrscheinlich am besten, Bigint als ein dynamisch zugewiesenes Array von vorzeichenlosen 32-Bit-Ganzzahlen zu speichern, sodass Ihre Arithmetik in 64 Bit passen kann. Sie können Ihr Zeichen separat behandeln, als eine Member-Variable der Klasse, oder Sie können 2'-Komplement-Arithmetik verwenden (so werden signed int typischerweise dargestellt).

Die Standard-C <stdint.h> Include-Datei definiert uint32_t und uint64_t, so dass plattformabhängige Integer-Typen vermieden werden können. Oder, (wenn Ihre Plattform diese nicht bietet), können Sie diese Art von Sache selbst improvisieren und definieren - vorzugsweise in einer separaten "platform_dependent.h" Datei ...

+0

2-s-Komplement ist nicht einfach für dynamische Länge Bigints tun (und nicht viel kaufen), aber Ich stimme dem Rest zu. – Sopel