Es hängt davon ab, welche Operationen Sie ausführen werden. Bitte bieten Sie weitere Informationen.
Eversor
@eversor Können Sie mir beschreiben, welcher Datentyp für verschiedene Vorgänge verwendet werden soll?
Questborn
1
Ich mache Berechnungen, bei denen ich Cent genau darstellen muss.
Questborn
Können Sie den größten Geldbetrag vorhersagen, den Ihre App benötigt? Und nach Ihren Berechnungen werden es einfache (Ergänzungen usw.) oder komplexere Finanzoperationen sein?
Eversor
Antworten:
133
Java hat eine CurrencyKlasse, die die ISO 4217-Währungscodes darstellt.
BigDecimalist der beste Typ für die Darstellung von Währungsdezimalwerten.
Joda Money hat eine Bibliothek zur Darstellung von Geld bereitgestellt.
@ Borat: Wenn Sie wissen, was Sie tun, können Sie diesen Artikel von Peter Lawrey lesen. Aber es scheint mindestens so mühsam zu sein, alle Rundungen durchzuführen, wie BigDecimals zu verwenden.
Nathan Hughes
35
"Wenn ich für jedes Mal einen Cent hätte, wenn ich jemanden gesehen hätte, der FLOAT zum Speichern von Währungen verwendet, hätte ich 999,997634 $" - Bill Karwin
Collin Krawll
36
Sie können die Geld- und Währungs-API (JSR 354) verwenden . Sie können diese API in verwenden, sofern Sie Ihrem Projekt entsprechende Abhängigkeiten hinzufügen.
Fügen Sie für Java 8 die folgende Referenzimplementierung als Abhängigkeit zu Ihrer hinzu pom.xml:
Was ist mit Serialisierung und Speichern in DB? Welches Format sollte für das Senden über Kabel verwendet werden?
Paweł Szczur
1
Ich glaube, dass Oracle Againts einschließlich Java Money in Java 9 gewidmet hat. Wirklich eine Schande. Aber tolle Antwort. Wir können es immer noch mit Maven
Borjab am
3
Haben Sie eine Quelle für Oracle, die sich gegen die Aufnahme von Java Money in Java 9 entscheidet?
Abdull
26
Ein ganzzahliger Typ, der den kleinstmöglichen Wert darstellt. Mit anderen Worten, Ihr Programm sollte in Cent und nicht in Dollar / Euro denken.
Dies sollte Sie nicht davon abhalten, die GUI wieder in Dollar / Euro umwandeln zu lassen.
Denken Sie daran, dass der Geldbetrag die Größe von int
eversor
5
@eversor, der über 20 Millionen Dollar benötigen würde, die meisten Apps würden nicht so viel brauchen, wenn sie lange dauern, wird ausreichen, da nicht einmal unsere Regierungen genug Geld verarbeiten, um das zu überfluten
Ratschenfreak
4
@ratchetfreak Wahrscheinlich besser, als lange zu verwenden.
Trognanders
4
Viele Banken verwalten weitaus größere Geldsummen als 20.000.000 USD pro Tag. Dies berücksichtigt nicht einmal Währungen wie den Yen mit hohen Wechselkursen zum Dollar. Ganzzahlige Typen sind möglicherweise am besten geeignet, um Rundungsprobleme zu vermeiden, obwohl sie bei Zins- und Wechselkursberechnungen unübersichtlich werden. Abhängig von der Anwendung benötigen Sie jedoch möglicherweise einen 64-Bit-Integer-Typ.
Alchymist
Im Idealfall wirkt sich der Rundungsfehler (3333,3 => 3333,0) nicht so stark auf den Endwert aus (in diesem Fall auf den tatsächlichen Wert, obwohl dies der Fall ist) gefährlich anzunehmen, dass es niemals wird). Dies ist besonders wichtig, wenn Sie viele Berechnungen hintereinander durchführen, bevor Ihr Benutzer das Ergebnis sieht, da sich die Rundungsfehler verschlimmern.
JSR 354 bietet eine API zum Darstellen, Transportieren und Durchführen umfassender Berechnungen mit Geld und Währung. Sie können es von diesem Link herunterladen:
Eine API für den Umgang mit z. B. Geldbeträgen und Währungen
APIs zur Unterstützung austauschbarer Implementierungen
Fabriken zum Erstellen von Instanzen der Implementierungsklassen
Funktionalität zur Berechnung, Umrechnung und Formatierung von Geldbeträgen
Java-API für die Arbeit mit Geld und Währungen, die in Java 9 enthalten sein soll.
Alle Spezifikationsklassen und Schnittstellen befinden sich im Paket javax.money. *.
Beispielbeispiele für JSR 354: Geld- und Währungs-API:
Ein Beispiel für das Erstellen eines MonetaryAmount und das Drucken auf der Konsole sieht folgendermaßen aus:
MonetaryAmountFactory<?> amountFactory =Monetary.getDefaultAmountFactory();MonetaryAmount monetaryAmount = amountFactory.setCurrency(Monetary.getCurrency("EUR")).setNumber(12345.67).create();MonetaryAmountFormat format =MonetaryFormats.getAmountFormat(Locale.getDefault());System.out.println(format.format(monetaryAmount));
Bei Verwendung der Referenzimplementierungs-API ist der erforderliche Code viel einfacher:
MonetaryAmount monetaryAmount =Money.of(12345.67,"EUR");MonetaryAmountFormat format =MonetaryFormats.getAmountFormat(Locale.getDefault());System.out.println(format.format(monetaryAmount));
Die API unterstützt auch Berechnungen mit MonetaryAmounts:
// getting CurrencyUnits by localeCurrencyUnit yen =MonetaryCurrencies.getCurrency(Locale.JAPAN);CurrencyUnit canadianDollar =MonetaryCurrencies.getCurrency(Locale.CANADA);
MonetaryAmount verfügt über verschiedene Methoden, mit denen Sie auf die zugewiesene Währung, den numerischen Betrag, ihre Genauigkeit und vieles mehr zugreifen können:
MonetaryAmount monetaryAmount =Money.of(123.45, euro);CurrencyUnit currency = monetaryAmount.getCurrency();NumberValue numberValue = monetaryAmount.getNumber();int intValue = numberValue.intValue();// 123double doubleValue = numberValue.doubleValue();// 123.45long fractionDenominator = numberValue.getAmountFractionDenominator();// 100long fractionNumerator = numberValue.getAmountFractionNumerator();// 45int precision = numberValue.getPrecision();// 5// NumberValue extends java.lang.Number. // So we assign numberValue to a variable of type NumberNumber number = numberValue;
MonetaryAmounts können mit einem Rundungsoperator gerundet werden:
Das alles ist schön, aber wie Federico oben vorgeschlagen hat, sieht es nur dann langsamer aus als BigDecimal :-)) schlechter Witz, aber ich werde es jetzt 1 Jahr später testen ...
Kensai
6
Sie sollten BigDecimal verwenden , um Geldwerte darzustellen. Es ermöglicht Ihnen die Verwendung einer Vielzahl von Rundungsmodi. In Finanzanwendungen ist der Rundungsmodus häufig eine schwierige Anforderung, die möglicherweise sogar gesetzlich vorgeschrieben ist.
Ich habe ein Microbenchmark (JMH) erstellt, um Moneta (Implementierung von Java Currency JSR 354) mit BigDecimal hinsichtlich der Leistung zu vergleichen.
Überraschenderweise scheint die Leistung von BigDecimal besser zu sein als die von Moneta. Ich habe folgende Moneta-Konfiguration verwendet:
Interessant, ich werde den gleichen Test mit den neuesten Sachen auf JDK9
Kensai
4
Für den einfachen Fall (eine Währung) it'is genug Integer/ Long. Halten Sie Geld in Cent (...) oder Hundertstel / Tausendstel Cent (jede Präzision, die Sie mit festem Teiler benötigen)
BigDecimal ist der beste Datentyp für die Währung.
Es gibt eine ganze Reihe von Währungscontainern, aber alle verwenden BigDecimal als zugrunde liegenden Datentyp. Mit BigDecimal werden Sie nichts falsch machen, wahrscheinlich mit BigDecimal.ROUND_HALF_EVEN-Rundung.
Ich benutze gerne kleine Typen die entweder ein Double, BigDecimal oder Int umschließen, wie in früheren Antworten vorgeschlagen. (Ich würde ein Double verwenden, wenn keine Präzisionsprobleme auftreten).
Ein kleiner Typ gibt Ihnen Sicherheit beim Schreiben, damit Sie ein doppeltes Geld nicht mit anderen doppelten verwechseln.
Antworten:
Java hat eine
Currency
Klasse, die die ISO 4217-Währungscodes darstellt.BigDecimal
ist der beste Typ für die Darstellung von Währungsdezimalwerten.Joda Money hat eine Bibliothek zur Darstellung von Geld bereitgestellt.
quelle
Sie können die Geld- und Währungs-API (JSR 354) verwenden . Sie können diese API in verwenden, sofern Sie Ihrem Projekt entsprechende Abhängigkeiten hinzufügen.
Fügen Sie für Java 8 die folgende Referenzimplementierung als Abhängigkeit zu Ihrer hinzu
pom.xml
:Diese Abhängigkeit wird transitiv
javax.money:money-api
als Abhängigkeit hinzugefügt .Sie können dann die API verwenden:
quelle
Ein ganzzahliger Typ, der den kleinstmöglichen Wert darstellt. Mit anderen Worten, Ihr Programm sollte in Cent und nicht in Dollar / Euro denken.
Dies sollte Sie nicht davon abhalten, die GUI wieder in Dollar / Euro umwandeln zu lassen.
quelle
BigDecimal kann verwendet werden. Eine gute Erklärung, warum Float oder Double nicht verwendet werden, finden Sie hier: Warum nicht Double oder Float zur Darstellung der Währung verwenden?
quelle
JSR 354: Geld- und Währungs-API
JSR 354 bietet eine API zum Darstellen, Transportieren und Durchführen umfassender Berechnungen mit Geld und Währung. Sie können es von diesem Link herunterladen:
JSR 354: Download der Geld- und Währungs-API
Die Spezifikation besteht aus folgenden Dingen:
Beispielbeispiele für JSR 354: Geld- und Währungs-API:
Ein Beispiel für das Erstellen eines MonetaryAmount und das Drucken auf der Konsole sieht folgendermaßen aus:
Bei Verwendung der Referenzimplementierungs-API ist der erforderliche Code viel einfacher:
Die API unterstützt auch Berechnungen mit MonetaryAmounts:
CurrencyUnit und MonetaryAmount
MonetaryAmount verfügt über verschiedene Methoden, mit denen Sie auf die zugewiesene Währung, den numerischen Betrag, ihre Genauigkeit und vieles mehr zugreifen können:
MonetaryAmounts können mit einem Rundungsoperator gerundet werden:
Bei der Arbeit mit Sammlungen von MonetaryAmounts stehen einige nützliche Dienstprogrammmethoden zum Filtern, Sortieren und Gruppieren zur Verfügung.
Benutzerdefinierte MonetaryAmount-Operationen
Ressourcen:
Umgang mit Geld und Währungen in Java mit JSR 354
Einblick in die Java 9 Money and Currency API (JSR 354)
Siehe auch: JSR 354 - Währung und Geld
quelle
Sie sollten BigDecimal verwenden , um Geldwerte darzustellen. Es ermöglicht Ihnen die Verwendung einer Vielzahl von Rundungsmodi. In Finanzanwendungen ist der Rundungsmodus häufig eine schwierige Anforderung, die möglicherweise sogar gesetzlich vorgeschrieben ist.
quelle
Ich würde Joda Money verwenden
Es ist immer noch in Version 0.6, sieht aber sehr vielversprechend aus
quelle
Ich habe ein Microbenchmark (JMH) erstellt, um Moneta (Implementierung von Java Currency JSR 354) mit BigDecimal hinsichtlich der Leistung zu vergleichen.
Überraschenderweise scheint die Leistung von BigDecimal besser zu sein als die von Moneta. Ich habe folgende Moneta-Konfiguration verwendet:
org.javamoney.moneta.Money.defaults.precision = 19 org.javamoney.moneta.Money.defaults.roundingMode = HALF_UP
Ergebend
Bitte zögern Sie nicht, mich zu korrigieren, wenn mir etwas fehlt
quelle
Für den einfachen Fall (eine Währung) it'is genug
Integer
/Long
. Halten Sie Geld in Cent (...) oder Hundertstel / Tausendstel Cent (jede Präzision, die Sie mit festem Teiler benötigen)quelle
BigDecimal ist der beste Datentyp für die Währung.
Es gibt eine ganze Reihe von Währungscontainern, aber alle verwenden BigDecimal als zugrunde liegenden Datentyp. Mit BigDecimal werden Sie nichts falsch machen, wahrscheinlich mit BigDecimal.ROUND_HALF_EVEN-Rundung.
quelle
Ich benutze gerne kleine Typen die entweder ein Double, BigDecimal oder Int umschließen, wie in früheren Antworten vorgeschlagen. (Ich würde ein Double verwenden, wenn keine Präzisionsprobleme auftreten).
Ein kleiner Typ gibt Ihnen Sicherheit beim Schreiben, damit Sie ein doppeltes Geld nicht mit anderen doppelten verwechseln.
quelle