2008-10-07 6 views
64

Derzeit bin ich borrowing java.math.BigInteger from the J# libraries as described here. Da ich noch nie eine Bibliothek für die Arbeit mit großen Ganzzahlen verwendet habe, scheint dies langsam zu sein, in der Größenordnung von 10-mal langsamer, sogar für ulong Längenzahlen. Hat jemand bessere (vorzugsweise freie) Bibliotheken, oder ist dieses Leistungsniveau normal?Große ganze Zahlen in C#

+0

schön Link. Ein paar Edelsteine ​​dort. –

+3

Das einzige Problem ist, dass die J # redistributables installiert werden müssen. Die Tatsache, dass J # alles andere als tot ist (es war nicht in VS 2008 atleast), hilft wahrscheinlich nicht dabei, das zu fördern. –

+0

J # dient nur dazu, die Migration bestehender Java-Projekte nach .NET zu erleichtern. Ich würde definitiv keine seiner Bibliotheken in ein neues Projekt integrieren. – MusiGenesis

Antwort

63

Ab .NET 4.0 können Sie die System.Numerics.BigInteger-Klasse verwenden. Siehe Dokumentation hier: http://msdn.microsoft.com/en-us/library/system.numerics.biginteger(v=vs.110).aspx

Eine andere Alternative ist die IntX Klasse.

IntX ist ein beliebiger Genauigkeit ganzen Zahlen Bibliothek in reinem C# geschrieben 2.0 mit schnellem - O (N · log N) - Multiplikation/Division Algorithmen Implementierung. Es bietet alle grundlegenden Operationen auf ganze Zahlen wie Addition, Multiplikation, Vergleichen, bitweise usw. Verschiebung

+26

Für den Datensatz, die 'System.Numerics' Assembly wird nicht standardmäßig in neuen Projekten referenziert, so dass dies hinzugefügt werden muss, bevor' BigInteger' verwendet werden kann. –

+0

Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf Verweise> Verweis hinzufügen> Nach Zahlen suchen, und überprüfen Sie die gefundene Referenz. Jetzt können Sie hinzufügen "using System.Numerics;" an der Spitze Ihrer .cs-Datei – Jan

3

Ich bin mir nicht sicher über die Leistung, aber IronPython hat auch eine BigInteger-Klasse. Es befindet sich im Microsoft.Scripting.Math-Namespace.

2

Ja, es wird langsam sein, und 10-fache Differenz ist ungefähr das, was ich erwarten würde. BigInt verwendet ein Array, um eine beliebige Länge darzustellen, und alle Operationen müssen manuell ausgeführt werden (im Gegensatz zu den meisten Berechnungen, die direkt mit der CPU durchgeführt werden können)

Ich weiß nicht einmal, ob es handkodiert ist Assembly wird Ihnen einen Leistungsgewinn von über 10x bringen, das ist verdammt nah. Ich würde nach anderen Möglichkeiten suchen, um es zu optimieren - manchmal gibt es je nach Matheproblem kleine Tricks, die Sie tun können, um es schneller zu machen.

2

Ich verwendete Biginteger bei einem früheren Job. Ich weiß nicht, welche Art von Performance Sie benötigen. Ich habe es in einer performance-intensiven Situation nicht benutzt, hatte aber nie Probleme damit.

2

Das mag wie ein seltsamer Vorschlag klingen, aber haben Sie den decimal Typ getestet, um zu sehen, wie schnell es funktioniert?

Der Dezimalbereich ist ± 1,0 × 10^-28 bis ± 7,9 × 10^28, so dass es immer noch nicht groß genug sein kann, aber es ist größer als ein ulong.

Es sollte in .NET 3.5 eine BigInteger-Klasse geben, aber it got cut.

+0

Ja, ich habe diese Ankündigung gesehen, als ich ursprünglich nach einer BigInt-Bibliothek gesucht habe. Das macht mich traurig. Naja. –

+0

Sie müssten vorsichtig sein - die Verwendung einer Dezimalzahl könnte zu Rundungsproblemen führen. – Blorgbeard

+0

Dezimal verursacht keine Rundungsfehler. Es ist kein Fließkomma. – Kibbee

4

Ich denke, Sie könnten die Implementierung optimieren, wenn Sie alle Operationen auf BigInts ausführen, die Ergebnisse kleiner als ein nativer Typ (z. B. int64) auf die nativen Typen zurückgeben und nur mit dem großen Array umgehen, wenn Sie gehen Überlaufen.

bearbeiten Diese implementation on codeproject scheint nur 7-mal langsamer ... Aber mit der obigen Optimierung könnte man es fast identisch mit nativen Typen für kleine Zahlen auszuführen bekommen.

+0

Ich glaube, dass die J # -Bibliothek Byte intern verwendet, es hat zumindest eine ToByteArray() -Funktion und keine andere ToArray() -Funktion. Dies könnte eine Idee sein, wenn ich meine eigene rollen wollte, aber ich bin nicht allzu begeistert von dieser Idee. –

+0

Mit welchen Daten arbeiten Sie im Allgemeinen? Wird die Int64-Größe regelmäßig überfüllt oder ist das eine Ausnahme? –

+0

Ich mache es meistens von Fall zu Fall und setze es auf BigInt, wenn ich mit einem überprüften {} -Block auf einen Überlauf stoße. Wenn es das einmal tut, dann gibt es eine ziemlich gute Chance, dass es es wiederholt und oft tun wird. –

1

Dies wird Ihnen nicht helfen, aber es sollte eine BigInteger-Klasse in .Net 3.5 sein; Es wurde geschnitten, aber aus den Aussagen von PDC wird es in .Net 4.0 sein. Sie haben offensichtlich viel Zeit damit verbracht, sie zu optimieren, also sollte die Leistung viel besser sein als das, was Sie jetzt bekommen.

Ferner diese Frage ist im Wesentlichen ein Duplikat How can I represent a very large integer in .NET?

+0

BigInteger ist in 3.5 aber es ist eine interne Klasse.;) Es ist einfach nicht zur Prime Time bereit. –

1

Siehe die Antworten in diesen thread. Sie müssen eine der verfügbaren großen Integer-Bibliotheken/Klassen von Drittanbietern verwenden oder auf C# 4.0 warten, die einen systemeigenen BigInteger-Datentyp enthalten.

9

F# wird auch mit einem geliefert. Sie können es unter Microsoft.FSharp.Math bekommen.

8

Die System.Numerics.BigInteger Klasse in .NET 4.0 basiert auf Microsoft.SolverFoundation.Common.BigInteger von Microsoft Research.

Die Klasse BigInteger der Solver Foundation sieht sehr performant aus. Ich bin mir nicht sicher, unter welcher Lizenz es veröffentlicht wird, aber Sie können es erhalten here (downloaden und installieren Sie Solver Foundation und finden Sie die Microsoft.Solver.Foundation.dll).

4

Hier sind einige Implementierungen von BigInteger in C#. ich verwendet habe, BigInteger, funktioniert ziemlich schnell (ich es in Compact verwendet habe)

Bouncy Castle

Mono