Cela dépend des opérations que vous allez faire. Veuillez offrir plus d'informations.
eversor
@eversor Pouvez-vous me donner une description du type de données à utiliser pour différentes opérations?
questborn
1
Je fais des calculs qui m'obligent à représenter avec précision les cents.
questborn
Êtes-vous en mesure de prédire la plus grosse somme d'argent que votre application devra gérer? Et, vos calculs, vont-ils être des opérations financières simples (aditions etc.) ou plus complexes?
Eversor
Réponses:
133
Java a une Currencyclasse qui représente les codes de devise ISO 4217.
BigDecimalest le meilleur type pour représenter les valeurs décimales des devises.
Joda Money a fourni une bibliothèque pour représenter l'argent.
@Borat: vous pouvez si vous savez ce que vous faites, voir cet article de Peter Lawrey. mais il semble au moins aussi compliqué de faire tout l'arrondi que d'utiliser BigDecimals.
Nathan Hughes
35
"Si j'avais un sou pour chaque fois que j'ai vu quelqu'un utiliser FLOAT pour stocker des devises, j'aurais 999,997634 $" - Bill Karwin
Collin Krawll
36
Vous pouvez utiliser l' API Money and Currency (JSR 354) . Vous pouvez utiliser cette API dans, à condition d'ajouter les dépendances appropriées à votre projet.
Pour Java 8, ajoutez l'implémentation de référence suivante en tant que dépendance à votre pom.xml:
Qu'en est-il de la sérialisation et de l'enregistrement dans la base de données? Quel format doit être utilisé pour l'envoi par fil?
Paweł Szczur
1
Je crois qu'Oracle a dédié à nouveau notamment Java Money dans Java 9. Vraiment dommage. Mais bonne réponse. Nous pouvons toujours l'utiliser avec Maven
borjab
3
Avez-vous une source pour qu'Oracle décide de ne pas inclure Java Money dans Java 9?
Abdull
25
Un type intégral représentant la plus petite valeur possible. En d'autres termes, votre programme devrait penser en centimes et non en dollars / euros.
Cela ne devrait pas vous empêcher de demander à l'interface graphique de le traduire en dollars / euros.
@eversor qui aurait besoin de plus de 20 millions de dollars, la plupart des applications n'auraient pas besoin de beaucoup si elles le font longtemps sera suffisant car même nos gouvernements ne gèrent pas assez d'argent pour déborder cela
ratchet freak
4
@ratchetfreak Il vaut probablement mieux utiliser un long alors.
trognanders
5
De nombreuses banques gèrent des sommes beaucoup plus importantes que 20 000 000 $ chaque jour. Cela ne tient même pas compte des devises comme le yen avec des taux de change élevés par rapport au dollar. Les types entiers peuvent être les meilleurs pour éviter les problèmes d'arrondi bien qu'ils soient compliqués avec les calculs des taux d'intérêt et de change. Cependant, selon l'application, vous pouvez avoir besoin d'un type entier 64 bits.
Alchymist
Idéalement des microdollars, en fait, comme si vous faisiez par exemple 10 $ / 3, l'erreur d'arrondi (3333,3 => 3333,0) n'affecte pas autant la valeur finale (dans ce cas, elle n'a pas du tout d'impact sur la valeur réelle, bien qu'elle soit dangereux de supposer qu'il ne le sera jamais). Ceci est particulièrement important si vous effectuez de nombreux calculs d'affilée avant que votre utilisateur ne voie le résultat, car les erreurs d'arrondi s'aggraveront.
JSR 354 fournit une API pour représenter, transporter et effectuer des calculs complets avec Money et Currency. Vous pouvez le télécharger à partir de ce lien:
Une API pour gérer par exemple les montants monétaires et les devises
API pour prendre en charge les implémentations interchangeables
Usines de création d'instances des classes d'implémentation
Fonctionnalité pour les calculs, la conversion et le formatage des montants monétaires
API Java pour travailler avec Money et Devises, qui devrait être incluse dans Java 9.
Toutes les classes de spécifications et interfaces se trouvent dans le package javax.money. *.
Exemples d'exemples de JSR 354: API Money and Currency:
Un exemple de création d'un MonetaryAmount et de son impression sur la console ressemble à ceci:
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));
Lors de l'utilisation de l'API d'implémentation de référence, le code nécessaire est beaucoup plus simple:
MonetaryAmount monetaryAmount =Money.of(12345.67,"EUR");MonetaryAmountFormat format =MonetaryFormats.getAmountFormat(Locale.getDefault());System.out.println(format.format(monetaryAmount));
L'API prend également en charge les calculs avec MonetaryAmounts:
// getting CurrencyUnits by localeCurrencyUnit yen =MonetaryCurrencies.getCurrency(Locale.JAPAN);CurrencyUnit canadianDollar =MonetaryCurrencies.getCurrency(Locale.CANADA);
MonetaryAmount dispose de différentes méthodes qui permettent d'accéder à la devise attribuée, au montant numérique, à sa précision et plus encore:
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 peut être arrondi à l'aide d'un opérateur d'arrondi:
Lorsque vous travaillez avec des collections de MonetaryAmounts, de belles méthodes utilitaires de filtrage, de tri et de regroupement sont disponibles.
Tout cela est bien, mais comme Federico l'a suggéré ci-dessus, cela semble plus lent que BigDecimal :-)) mauvaise blague alors seulement, mais je vais le tester maintenant 1 an plus tard ...
kensai
6
Vous devez utiliser BigDecimal pour représenter les valeurs monétaires. Il vous permet d'utiliser une variété de modes d'arrondi , et dans les applications financières, le mode d'arrondi est souvent une exigence stricte qui peut même être imposée par la loi.
Intéressant, je vais lancer le même test avec les derniers trucs sur JDK9
kensai
4
Pour un cas simple (une devise) c'est suffisant Integer/ Long. Gardez l'argent en cents (...) ou centième / millième de cents (toute précision dont vous avez besoin avec un diviseur fixe)
BigDecimal est le meilleur type de données à utiliser pour la devise.
Il existe de nombreux conteneurs pour la devise, mais ils utilisent tous BigDecimal comme type de données sous-jacent. Vous ne vous tromperez pas avec BigDecimal, probablement en utilisant l'arrondi BigDecimal.ROUND_HALF_EVEN.
J'aime utiliser les petits types qui encapsulerait un double, BigDecimal ou un int comme les réponses précédentes l'ont suggéré. (J'utiliserais un double à moins que des problèmes de précision ne surviennent).
Un type minuscule vous donne la sécurité de type afin que vous ne confondiez pas un double argent avec d'autres doubles.
Réponses:
Java a une
Currency
classe qui représente les codes de devise ISO 4217.BigDecimal
est le meilleur type pour représenter les valeurs décimales des devises.Joda Money a fourni une bibliothèque pour représenter l'argent.
la source
Vous pouvez utiliser l' API Money and Currency (JSR 354) . Vous pouvez utiliser cette API dans, à condition d'ajouter les dépendances appropriées à votre projet.
Pour Java 8, ajoutez l'implémentation de référence suivante en tant que dépendance à votre
pom.xml
:Cette dépendance s'ajoutera de
javax.money:money-api
manière transitoire en tant que dépendance.Vous pouvez ensuite utiliser l'API:
la source
Un type intégral représentant la plus petite valeur possible. En d'autres termes, votre programme devrait penser en centimes et non en dollars / euros.
Cela ne devrait pas vous empêcher de demander à l'interface graphique de le traduire en dollars / euros.
la source
BigDecimal peut être utilisé, une bonne explication de pourquoi ne pas utiliser Float ou Double peut être vue ici: Pourquoi ne pas utiliser Double ou Float pour représenter la devise?
la source
JSR 354: API Money and Currency
JSR 354 fournit une API pour représenter, transporter et effectuer des calculs complets avec Money et Currency. Vous pouvez le télécharger à partir de ce lien:
JSR 354: Téléchargement de l'API Money and Currency
La spécification comprend les éléments suivants:
Exemples d'exemples de JSR 354: API Money and Currency:
Un exemple de création d'un MonetaryAmount et de son impression sur la console ressemble à ceci:
Lors de l'utilisation de l'API d'implémentation de référence, le code nécessaire est beaucoup plus simple:
L'API prend également en charge les calculs avec MonetaryAmounts:
CurrencyUnit et MonetaryAmount
MonetaryAmount dispose de différentes méthodes qui permettent d'accéder à la devise attribuée, au montant numérique, à sa précision et plus encore:
MonetaryAmounts peut être arrondi à l'aide d'un opérateur d'arrondi:
Lorsque vous travaillez avec des collections de MonetaryAmounts, de belles méthodes utilitaires de filtrage, de tri et de regroupement sont disponibles.
Opérations MonetaryAmount personnalisées
Ressources:
Gestion de l'argent et des devises en Java avec JSR 354
Examen de l'API Java 9 Money and Currency (JSR 354)
Voir aussi: JSR 354 - Monnaie et argent
la source
Vous devez utiliser BigDecimal pour représenter les valeurs monétaires. Il vous permet d'utiliser une variété de modes d'arrondi , et dans les applications financières, le mode d'arrondi est souvent une exigence stricte qui peut même être imposée par la loi.
la source
j'utiliserais Joda Money
Il est toujours à la version 0.6 mais semble très prometteur
la source
J'ai fait un microbenchmark (JMH) pour comparer Moneta (mise en œuvre de la devise java JSR 354) à BigDecimal en termes de performances.
Étonnamment, les performances de BigDecimal semblent meilleures que celles de moneta. J'ai utilisé la configuration moneta suivante:
org.javamoney.moneta.Money.defaults.precision = 19 org.javamoney.moneta.Money.defaults.roundingMode = HALF_UP
Résultant en
N'hésitez pas à me corriger si quelque chose me manque
la source
Pour un cas simple (une devise) c'est suffisant
Integer
/Long
. Gardez l'argent en cents (...) ou centième / millième de cents (toute précision dont vous avez besoin avec un diviseur fixe)la source
BigDecimal est le meilleur type de données à utiliser pour la devise.
Il existe de nombreux conteneurs pour la devise, mais ils utilisent tous BigDecimal comme type de données sous-jacent. Vous ne vous tromperez pas avec BigDecimal, probablement en utilisant l'arrondi BigDecimal.ROUND_HALF_EVEN.
la source
J'aime utiliser les petits types qui encapsulerait un double, BigDecimal ou un int comme les réponses précédentes l'ont suggéré. (J'utiliserais un double à moins que des problèmes de précision ne surviennent).
Un type minuscule vous donne la sécurité de type afin que vous ne confondiez pas un double argent avec d'autres doubles.
la source