2008-11-10 7 views
18

Welche Bibliotheken für Java gibt es, die eine schnelle Implementierung für Gleitkomma- oder Festkommaoperationen mit einer Genauigkeit von mehreren tausend Stellen haben? Wie leistungsfähig sind sie?Java Fließkomma-Bibliothek mit hoher Präzision

Eine Voraussetzung für mich ist, dass es einen Multiplikationsalgorithmus implementiert, der besser ist als der naive Multiplikationsalgorithmus, der 4 mal so viel Zeit für eine 2 mal größere Anzahl von Ziffern benötigt (vergleiche Multiplication algorithms).

+0

Eine allgemeine Frage von einem Standpunkt von Interesse ... Was ist Ihre Anwendung, die mehrere tausend Dezimalstellen Genauigkeit erfordert? – Simon

+1

Dies ist ein Hobby, kein Job: Ich würde gerne mehr Ziffern von http://en.wikipedia.org/wiki/Feigenbaum_constant berechnen –

Antwort

35

Auf der Seite Arbitrary Precision Arithmetic sind drei Bibliotheken aufgeführt: java.math (enthält das erwähnte BigDecimal), und JScience. Ich mache eine kleine Geschwindigkeitsüberprüfung, die nur Addition und Multiplikation verwendet.

Das Ergebnis ist, dass für eine relativ kleine Anzahl von Ziffern BigDecimal OK ist (halb so schnell wie die anderen für 1000 Ziffern), aber wenn Sie mehr Ziffern verwenden, ist es weit weg - JScience ist etwa 4 mal schneller. Aber der klare Leistungsgewinner ist Apfloat. Die anderen Bibliotheken scheinen naive Multiplikationsalgorithmen zu verwenden, die Zeit proportional zum Quadrat der Anzahl der Stellen benötigen, aber die Zeit von Apfloat scheint fast linear zu wachsen. Auf 10000 Ziffern war es 4 mal so schnell wie JScience, aber auf 40000 Ziffern ist es 16 mal so schnell wie JScience.

Auf der anderen Seite: JScience bietet hervorragende Funktionalität für mathematische Probleme: Matrizen, Vektoren, symbolische Algorithmen, Lösung von Gleichungssystemen und was nicht. Also werde ich wahrscheinlich mit JScience gehen und später einen Wrapper schreiben, um Apfloat in die Algorithmen von JScience zu integrieren - aufgrund des guten Designs scheint dies leicht möglich.

(UPDATE: Ich schrieb eine Testsuite für die Nummer Paket JScience und eine Reihe von Bugs behoben Dies ging in Release 4.3.1 So kann ich empfehlen, Check-out...)

+2

Unterstützen einige der Bibliotheken trigonometrische Funktionen? –

+0

Solltest du sagen, dass JScience einen konstanten ~ 4-fachen Geschwindigkeitsvorteil beibehält, wenn du eine bestimmte Anzahl an Ziffern überschritten hast? Oder wird der Geschwindigkeitsunterschied für mehr Ziffern deutlicher? –

+0

@Asad Ich habe solche detaillierten Experimente nicht gemacht, aber ich nehme an, dass sie unterschiedliche Algorithmen mit unterschiedlichen Zeitkomplexitäten verwenden. (Zumindest für Multiplikation und so weiter.) So wird die Geschwindigkeitsdifferenz immer größer, je mehr Ziffern Sie haben. Aber wenn Sie viel mehr Ziffern wollen, müssen Sie Ihre eigenen Experimente machen, und vielleicht gibt es dafür sogar noch bessere Bibliotheken. –

5

Haben Sie die Leistung von BigDecimal überprüft? Ich kann im JavaDoc nichts Offensichtliches sehen, aber es wäre sicherlich meine erste Anlaufstelle.

+1

Für sehr hohe Präzision ist das viel langsamer. Ich würde dies nur empfehlen, wenn Sie nur Zehnerstellen haben oder sich nicht um die Geschwindigkeit kümmern. –

+0

@hstoerr: Es ist gut, dass Sie es überprüft haben - aber ich denke, der Ansatz von "testen Sie die einfachste Sache, die funktioniert" (wo eingebaut ist ein wesentlicher Ausgangspunkt Vorteil) ist immer noch ein guter erster Schritt :) –

+0

BigDecimal ist ziemlich begrenzt, zum Beispiel unterstützt es nicht sqrt im Gegensatz zu JScience – Tomasz

2

Sie können sich die JScience Bibliothek und ihre Real Nummer Klasse ansehen. Ich bin nicht sicher, wie die Leistung relativ zu BigDecimal ist, aber das Ziel der Bibliothek ist es, hochgradig abgestimmte Klassen für wissenschaftliche Anwendungen bereitzustellen, was ein gutes Zeichen zu sein scheint.

-3

Apfloat bietet hohe Präzision auf der Mantisse, aber scheint weniger als übliche Präzision auf dem Exponenten zu geben (basierend auf der Tatsache, dass es mit "Logarithmus von Null" für Werte kollidiert, die double verarbeiten kann). Es ist also nicht für große Zahlen nützlich.

Auch sagt die Dokumentation:

„A pitfall existiert mit dem Konstrukteuren Apfloat (float, long) und Apfloat (Doppel, lang) Da floats und doubles werden intern immer in Radix 2 dargestellt, um die Konvertierung zu. jedes andere Radix verursacht normalerweise Rundungsfehler, und der resultierende Apfloat wird nicht auf die gewünschte Anzahl von Stellen genau sein

Zum Beispiel kann 0,3 nicht genau in Basis 2 dargestellt werden. Wenn Sie ein Apfloat wie erstellen neuer Apfloat (0.3f, 1000), die resultierende Zahl wird nicht auf 1000 Ziffern genau sein, sondern nur auf ungefähr 7 Ziffern (in Radix 10). Tatsächlich wird die resultierende Zahl ungefähr so ​​sein wie 0.30000001192092896 ... "

Dies scheint Apfloat minimal nützlich zu machen.

BigDecimal hat keine Logarithmusfunktion, und die Dokumentation sagt nicht, ob es Ihnen erlaubt, größere Zahlen als ein Doppel zu machen; der Exponent ist 32 Bit, eine Art von.

+1

Eigentlich Phil, der Grund für diese Falle liegt darin, dass Sie den Apfloat mit einem Float oder Double konstruieren. Die Ungenauigkeit liegt daran, dass Sie eine ungenaue Zahl übergeben. Wenn Sie sich die Zeit genommen hätten, den nächsten Absatz zu lesen, würden Sie sehen, dass Sie unendliche Genauigkeit haben können, wenn Sie es mit einer Zeichenkette konstruieren. – Snickers

+0

BigDecimal 0,3 wäre genau. Um dieses Beispiel zu nehmen. Hat Apfloat einen Konstruktor von BigDecimal? BigDecimal ist eine Art hybride Repräsentation, die Mantisse ist Base 2 (BigInteger), aber der Exponent ist Base 10. –