Question

Je comprends que BigDecimal est la meilleure pratique recommandée pour représenter les valeurs monétaires en Java. Qu'est ce que tu utilises? Existe-t-il une meilleure bibliothèque que vous préférez utiliser à la place?

Était-ce utile?

La solution

BigDecimal jusqu'au bout. J'ai entendu parler de personnes créant leurs propres classes Cash ou Money qui encapsulent une valeur en espèces avec la devise, mais sous la peau, il s'agit toujours d'un BigDecimal , probablement avec BigDecimal.ROUND_HALF_EVEN arrondi.

Modifier: comme le mentionne Don dans sa réponse , il existe des projets open source tels que timeandmoney , et je les en félicite pour avoir tenté d'empêcher les développeurs d'avoir pour réinventer la roue, je n’ai tout simplement pas assez confiance en une bibliothèque pré-alpha pour l’utiliser dans un environnement de production. De plus, si vous fouillez sous le capot, vous verrez ils utilisent aussi BigDecimal .

Autres conseils

Il peut être utile aux personnes arrivant ici par les moteurs de recherche de connaître JodaMoney: http: // www .joda.org / joda-money / .

Je n'exprime pas mon opinion ici, mais il existe de très bons arguments contre BigDecimal que quelqu'un devrait probablement jeter:

http://lemnik.wordpress.com/2011 / 03/25 / bigdecimal-and-your-money /

Une bibliothèque pratique que j'ai rencontrée précédemment est la bibliothèque Joda-Money . L'une de ses implémentations est en effet basée sur BigDecimal. Il est basé sur la spécification ISO-4217 pour les devises et peut prendre en charge une liste de devises personnalisée (chargée). via CVS).

Cette bibliothèque contient un petit nombre de fichiers que l’on peut parcourir rapidement si des modifications s’imposent. Joda-Money est publié sous la licence Apache 2.0.

Si vous n'utilisez que des dollars et des cents, j'utiliserais un long (compensé par 2 décimales). Si vous avez besoin de plus de détails, utilisez une grande décimale.

Dans les deux cas, j'étendrais probablement la classe de manière à avoir un .toString () qui utilise le format correct, et comme un endroit pour mettre en place d'autres méthodes qui pourraient être utilisées la décimale n'est pas ajustée)

En outre, si vous définissez votre propre classe et votre interface, vous pouvez remplacer l’implémentation à votre guise.

BigDecimal ou une autre représentation à point fixe est ce qui est généralement nécessaire pour de l'argent.

Les représentations et calculs

à virgule flottante ( Double , Flottant ) sont inexacts, ce qui conduit à des résultats erronés.

Vous devez faire très attention lorsque vous traitez avec du temps et de l'argent.

Lorsque vous travaillez avec de l'argent, j'espère que tout le monde devrait savoir qu'il ne faut jamais utiliser de float ou de double.

Mais je ne suis pas sûr de BigDecimal.

Dans la plupart des cas, tout ira bien si vous ne gardez que des cents dans un int ou long. De cette façon, vous ne traitez jamais avec une décimale.

Vous n’affichez les dollars que lorsque vous l’imprimez. Toujours travailler avec des cents internes en utilisant des entiers. Cela peut être délicat si vous devez diviser ou si vous devez utiliser Math.abs ().

Cependant, vous pourriez vous soucier d’un demi-cent, voire d’un centième. Je ne sais pas quel est le bon moyen de faire cela. Vous pourriez juste avoir besoin de traiter avec des millièmes de centimes et utiliser un long. Ou peut-être serez-vous obligé d'utiliser BigDecimal

Je lirais beaucoup plus à ce sujet, mais ignorerais tous ceux qui commencent à parler d’utiliser un float ou un double pour représenter l’argent. Ils ne font que demander des ennuis.

Je pense que mes conseils ne sont pas complets, alors mettez-y davantage. Vous avez affaire à des types dangereux!

Créer une classe Money est la voie à suivre. Utiliser BigDecimal (ou même un int) dessous. Ensuite, utilisez la classe Currency pour définir la convention d'arrondi.

Malheureusement, sans surcharge de l'opérateur Java, il est très désagréable de créer de tels types de base.

Il existe une meilleure bibliothèque, timeandmoney . OMI, il est de loin supérieur aux bibliothèques fournies par le JDK pour représenter ces deux concepts.

Certainement pas BigDecimal. Il y a tellement de règles spéciales pour l'arrondissement et la présentation que vous devez vous inquiéter.

Martin Fowler recommande la mise en place d'une classe dédiée Money pour représenter les montants en devise et qui implémente également des règles pour la conversion de devise.

Hé, voici un article très intéressant sur BigDecimal et un exemple illustrant pourquoi il est parfois utilisé au lieu de doubler. Didacticiel BigDecimal .

Vous pouvez utiliser la classe DecimalFormat pour afficher une valeur monétaire. Il fournit un support de localisation et est assez extensible.

Je voudrais encapsuler BigDecimal dans la classe Money qui a également une devise, tout comme une personne mentionnée ci-dessus. L'important est que vous fassiez une quantité extrême de tests unitaires, surtout si vous travaillez avec des devises différentes. En outre, il est judicieux d'ajouter un constructeur adapté prenant une chaîne ou une méthode fabrique faisant de même, de sorte que vous puissiez écrire vos tests à peu près comme ceci:

   assertEquals(Money.create("100.0 USD").add("10 GBP"),Money.create("116 USD"));

Il y a toujours des contraintes et des spécificités impliquées. Toute personne ne disposant pas d’une expérience suffisante pour comprendre les problèmes subtils exposés dans l’article suivant doit sérieusement reconsidérer sa décision avant de traiter avec des données financières réelles:

http://lemnik.wordpress.com/2011/ 03/25 / bigdecimal-and-your-money

BigDecimal n’est pas la seule représentation correcte ni la seule pièce du puzzle. Dans certaines conditions, l’utilisation d’une classe Money reposant sur des centimes stockés sous forme d’entier pourrait suffire et serait beaucoup plus rapide que BigDecimal. Oui, cela implique l’utilisation de dollars comme monnaie et limite les montants, mais de telles contraintes sont parfaitement acceptables pour de nombreux cas d’utilisation et toutes les monnaies ont des cas spéciaux pour les arrondis et les sous-dénominations de toute façon, il n’existe donc pas de critère "universel". solution.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top