2017-09-29 3 views
1

Je travaille avec BigDecimal et je sais que si je divise je dois utiliser MathContext et dire qui Scale et RoundingMode pour éviter ArithmeticException comme décrit dans la documentation:Java BigDecimal arrondit nécessaire avec l'addition?

Dans le cas de fracture, le quotient exact pourrait avoir une expansion décimale longue à l'infini ; par exemple, 1 divisé par 3. Si le quotient a un développement décimal non-terminating et que l'opération est spécifiée pour renvoyer un résultat exact, une ArithmeticException est levée.

Dans la méthode, je travaille sur je dois résumer les sommes provenant de notre base de données (qui sont arrondies à 2 décimales) avec des montants provenant d'un service externe, et je ne sais pas la mise à l'échelle exacte de ces montants (probabilités 3 décimales).

Ma question est: est-ce que je peux faire confiance à la méthode d'addition BigDecimal et l'utiliser sans arrondir et mettre à l'échelle ou c'est une bonne habitude de toujours spécifier l'échelle désirée?

Y a-t-il un cas particulier où l'addition et la soustraction peuvent augmenter ArithmeticException?

+0

Avez-vous réellement lu la documentation de la méthode add? Il indique clairement que si vous ne définissez pas une échelle elle-même, elle utilisera l'échelle maximale des deux opérandes. Donc "1.123 + 3" utilisera une échelle de 3 pour le résultat par défaut, ce qui est tout ce dont vous avez besoin pour une précision totale. –

+0

@OHGODSPIDERS oui je l'ai lu, mais je veux vraiment être sûr et j'ai encore des doutes à ce sujet. Et je suis curieux de savoir s'il est bon d'utiliser toujours les arrondis ou non. Cela me semble une question raisonnable. – amicoderozer

Répondre

1

BigDecimal.add() lancera ArithmeticException si l'échelle du résultat ne rentre pas dans un int.

Un exemple simple ajoute deux chiffres avec le maximum et les échelles minimum:

BigDecimal a = new BigDecimal(BigInteger.ONE, Integer.MIN_VALUE); 
BigDecimal b = new BigDecimal(BigInteger.ONE, Integer.MAX_VALUE); 
a.add(b); 

Si votre application doit fonctionner à cette échelle alors vous avez probablement quelques plus problèmes que se soucier de l'arithmétique exception. Ajouter des numéros sans utiliser MathContext maintiendra l'échelle correcte et vous donnera le résultat précis. En fonction des valeurs réelles, cette approche peut utiliser une quantité arbitraire de mémoire pour représenter des nombres de plus en plus longs, et des nombres plus longs prennent plus de temps à ajouter.

L'ajout de numéros sans utiliser MathContext et le rouding une fois après la sommation vous donneront le résultat précis arrondi au MathContext demandé. Les coûts de mémoire et de calcul sont les mêmes que dans le premier cas. L'utilisation de MathContext pour chaque addition produira un résultat qui peut différer du résultat de présumée d'une valeur arbitraire, mais la mémoire et la vitesse seront plus prévisibles. Le choix de l'une de ces approches dépend vraiment de la nature de la tâche. Il vous appartient donc d'évaluer et de choisir la bonne approche pour chaque cas particulier.

+0

Merci pour l'explication claire Oleg! – amicoderozer