Ich spiele mit der .NET BigInteger herum und frage mich im Grunde, welche Zahl - eine geschätzte Antwort wäre in Ordnung - der Punkt der Abweichung der Kurve von (der Graph von (für Operationen erforderliche Zeitzunahme ) vs (Wert von BigInteger))?
oder sind sie so konstruiert, dass sie eine glatte Kurve haben, wenn wir den Anstieg der für Operationen benötigten Zeit gegen den Wert von BigInteger von 1 bis unendlich zeichnen?
Angenommen, Arrays sind für die Verarbeitung von 50 Elementen ausgelegt. Dies bedeutet, dass, wenn ich 1 Element habe, Operationen f (1) Zeit sind. und wenn ich 2 Einzelteile habe, sind Operationen f (2) Zeit. Wenn ich 50 Elemente habe, sind Operationen f (50) Zeit. Da es jedoch nur für die Verarbeitung von 50 Elementen ausgelegt ist, sind die Operationen, die ausgeführt werden, wenn 51 Elemente vorliegen, g (51), wobei g (51)> f (51).
Bei richtiger Implementierung sollte die Komplexität der BigInteger-Arithmetik eine glatte Kurve sein. Zum Beispiel sollte die zeitliche Komplexität der Multiplikation O (NM) sein, wobei N die Anzahl der Stellen im ersten Multiplikanden und M die Anzahl der Stellen im zweiten Multiplikanden ist. Natürlich gibt es praktische Grenzen, in denen Sie N und M so groß wählen können, dass die Zahlen nicht in Ihre Maschine passen.
Gibt es / kennt jemand Dokumente, die behaupten, dass sie als solche implementiert sind?
Antworten:
Jede Zahl, die möglicherweise größer als ULong.MaxValue oder kleiner als Long.MinValue sein kann, sollte mit BigInteger dargestellt werden.
Wenn NICHT (Long.MinValue <= X <= ULong.MaxValue), dann BigInteger
BigInteger ist für zu große Zahlen, als dass normale Primitive damit umgehen können.
Wenn Ihre Ganzzahl beispielsweise außerhalb des Bereichs von Long liegt, sollten Sie wahrscheinlich BigInteger verwenden. Diese Fälle sind jedoch sehr selten und bei Verwendung dieser Klassen ist der Overhead erheblich höher als bei Verwendung ihrer primitiven Gegenstücke.
long
Ist beispielsweise 64 Bit breit und kann den Bereich von -9.223.372.036.854.775.808 bis 9.223.372.036.854.775.80 enthalten. ulong kann 0 bis 18.446.744.073.709.551.615 halten. Wenn Ihre Zahlen größer oder kleiner sind, ist BigInteger Ihre einzige OptionDas einzige Mal, dass ich sie in einer realen Anwendung gesehen habe, war eine Starchartting-Anwendung.
Siehe auch: Primitive Bereiche in .NET
quelle
In gewissem Sinne ist der Punkt von BigInteger nicht so sehr die absolute Größe, sondern die unbegrenzte Präzision. Gleitkommazahlen können ebenfalls sehr groß sein, haben jedoch eine begrenzte Genauigkeit. Mit BigInteger können Sie Arithmetik ausführen, ohne Rundungsfehler oder Überlauf befürchten zu müssen. Der Preis, den Sie zahlen, ist, dass es hunderte Male langsamer ist als Arithmetik mit gewöhnlichen Ganzzahlen oder Gleitkommazahlen.
Wie bereits erwähnt, kann ulong zwischen 0 und 18.446.744.073.709.551.615 liegen. Solange Sie in diesem Bereich bleiben, können Sie exakte Berechnungen durchführen. Wenn Sie sogar 1 über diesen Bereich hinausgehen, kommt es zu einem Überlauf. Daher lautet die Antwort auf Ihre Frage "BigInteger", wenn Sie eine exakte Arithmetik benötigen und die Wahrscheinlichkeit besteht, dass ein Zwischenergebnis 18.446.744.073.709.551.615 überschreitet.
Die meisten Probleme in Wissenschaft, Technik und Finanzen können mit den durch Gleitkommazahlen erzwungenen Näherungen leben und können sich die Zeitkosten der BigInteger-Arithmetik nicht leisten. Die meisten kommerziellen Berechnungen können nicht mit den Näherungen der Gleitkomma-Arithmetik leben, sondern arbeiten im Bereich von 0 bis 18.446.744.073.709.551.615, sodass sie normale Arithmetik verwenden können. BigInteger wird benötigt, wenn Algorithmen aus der Zahlentheorie verwendet werden, die Dinge wie Kryptographie beinhalten (man denke an 50-stellige Primzahlen). Es wird auch manchmal in kommerziellen Anwendungen verwendet, wenn exakte Berechnungen erforderlich sind, die Geschwindigkeit nicht zu wichtig ist und die Einrichtung eines geeigneten Festkommasystems zu schwierig ist.
Bei richtiger Implementierung sollte die Komplexität der BigInteger-Arithmetik eine glatte Kurve sein. Zum Beispiel sollte die zeitliche Komplexität der Multiplikation O (NM) sein, wobei N die Anzahl der Stellen im ersten Multiplikanden und M die Anzahl der Stellen im zweiten Multiplikanden ist. Natürlich gibt es praktische Grenzen, in denen Sie N und M so groß wählen können, dass die Zahlen nicht in Ihre Maschine passen.
Wenn Sie "Computing Complexity of Biginteger" googeln, erhalten Sie mehr Referenzen, als Sie sich vorstellen können. Eine, die direkt zu Ihrer Frage spricht, ist die folgende: Vergleich zweier Arithmetikpakete mit willkürlicher Genauigkeit .
quelle
Speicherlimit
BigInteger ist für die Speicherung auf das Array int angewiesen. Angenommen, die theoretische Grenze für die maximale Anzahl, die BigInteger darstellen kann, kann aus der in .net verfügbaren maximalen Array-Größe abgeleitet werden. Hier gibt es ein SO-Thema zu Arrays: Ermitteln, wie viel Speicher ich einem Array in C # zuweisen kann .
Unter der Annahme, dass wir die maximale Arraygröße kennen, können wir die maximale Anzahl schätzen, die BigInteger darstellen kann: (2 ^ 32) ^ max_array_size, wobei:
Dies ergibt eine Zahl mit 600 Millionen Dezimalstellen.
Leistungslimit
Für die Performance verwendet BigInteger den Karatsuba-Algorithmus zur Multiplikation und den linearen Algorithmus zum Addieren. Die Multiplikationskomplexität ist , das bedeutet, dass sie auch für große Zahlen ziemlich gut skaliert werden kann ( Komplexitätsdiagramm ). Je nach RAM-Größe und Prozessor-Cache kann es jedoch zu Leistungseinbußen kommen.
Solange die maximale Anzahl auf 2 GB begrenzt ist, werden Sie auf Abstiegsmaschinen keine unerwartete Leistungslücke sehen, aber wenn Sie weiterhin mit 600 Millionen Ziffern arbeiten, werden Sie sehr langsam sein.
quelle
Die Grenze ist Ihre Speichergröße (und die Zeit, die Sie haben). Sie können also wirklich große Zahlen haben. Wie Kevin sagte, muss man in der Kryptographie Zahlen mit einigen tausend (binären) Ziffern multiplizieren oder potenzieren, und dies ist problemlos möglich.
Natürlich werden die Algorithmen oft langsamer, wenn die Zahlen größer werden, aber nicht so viel langsamer.
Wenn Sie Zahlen im Mega-Ziffern-Bereich verwenden, möchten Sie vielleicht auch über andere Lösungen nachdenken - da das Rechnen mit ihnen auch sehr langsam wird.
quelle
Innerhalb der wissenschaftlichen Gemeinschaft gibt es einige Verwendungszwecke (z. B. den Abstand zwischen Galaxien, die Anzahl der Atome in einem Grasfeld usw.).
quelle
double
oderfloat
- Sie haben sowieso nicht die notwendige Präzision.Wie aus der Antwort von Kevin Cline hervorgeht, wurden BigNumbers in erster Linie zu den .NET-Bibliotheken hinzugefügt, da sie als Baustein für viele moderne kryptografische Algorithmen (digitale Signaturen, Verschlüsselung mit öffentlichen / privaten Schlüsseln usw.) benötigt wurden. Bei vielen modernen kryptografischen Algorithmen werden ganzzahlige Werte mit einer Größe von bis zu mehreren tausend Bit berechnet. Da die BigNumber-Klasse eine gut definierte und nützliche Klasse beschreibt, haben sie beschlossen, sie öffentlich zu machen (anstatt sie als internes Detail der kryptografischen APIs zu behalten).
quelle