54 votes

Définir la précision spécifique d'un BigDecimal

J'ai un XSD qui me demande d'utiliser un BigDecimal pour une lat/lon. Actuellement, je dispose de la lat/lon sous forme de doubles, et je les convertis en BigDecimal, mais je ne suis tenu d'utiliser qu'une précision d'environ 12 positions. Je n'ai pas réussi à trouver comment régler cela. Quelqu'un peut-il m'aider ?

95voto

Peter Lawrey Points 229686

Vous pouvez utiliser setScale() par exemple

double d = ...
BigDecimal db = new BigDecimal(d).setScale(12, BigDecimal.ROUND_HALF_UP);

45voto

David James Points 8344

Le titre de la question porte sur la précision. BigDecimal fait la distinction entre échelle et précision. L'échelle est le nombre de décimales. Vous pouvez considérer la précision comme le nombre de chiffres significatifs également connus sous le nom de chiffres significatifs.

Quelques exemples en Clojure.

(.scale     0.00123M) ; 5
(.precision 0.00123M) ; 3

(En Clojure, le M désigne un littéral BigDecimal. Vous pouvez traduire le Clojure en Java si vous le souhaitez, mais je trouve qu'il est plus compact que le Java).

Vous pouvez facilement augmenter l'échelle :

(.setScale 0.00123M 7) ; 0.0012300M

Mais vous ne pouvez pas diminuer la balance de la même manière :

(.setScale 0.00123M 3) ; ArithmeticException Rounding necessary

Vous devrez également passer un mode d'arrondi :

(.setScale 0.00123M 3 BigDecimal/ROUND_HALF_EVEN) ;
; Note: BigDecimal would prefer that you use the MathContext rounding
; constants, but I don't have them at my fingertips right now.

Il est donc facile de changer l'échelle. Mais qu'en est-il de la précision ? Ce n'est pas aussi facile que vous pourriez l'espérer !

Il est facile de diminuer la précision :

(.round 3.14159M (java.math.MathContext. 3)) ; 3.14M

Mais il n'est pas évident de savoir comment augmentation de la précision :

(.round 3.14159M (java.math.MathContext. 7)) ; 3.14159M (unexpected)

Pour les sceptiques, c'est pas il s'agit simplement de ne pas afficher les zéros de fin de ligne :

(.precision (.round 3.14159M (java.math.MathContext. 7))) ; 6 
; (same as above, still unexpected)

Pour information, Clojure est prudent avec les zéros de fin de ligne et sera les montrer :

4.0000M ; 4.0000M
(.precision 4.0000M) ; 5

Retour sur la piste... Vous pouvez essayer d'utiliser un BigDecimal mais il ne définit pas la précision au-delà du nombre de chiffres que vous spécifiez :

(BigDecimal. "3" (java.math.MathContext. 5)) ; 3M
(BigDecimal. "3.1" (java.math.MathContext. 5)) ; 3.1M

Il n'y a donc pas de moyen rapide de modifier la précision. J'ai passé du temps à me battre contre cela en rédigeant cette question et avec un projet sur lequel je travaille. Je considère cela, au mieux, comme une API CRAZYTOWN, et au pire comme un bug. Les gens. Sérieusement ?

Donc, d'après ce que je sais, si vous voulez changer la précision, vous devez suivre ces étapes :

  1. Recherche de la précision actuelle.
  2. Recherche l'échelle actuelle.
  3. Calculez le changement d'échelle.
  4. Définir la nouvelle échelle

Ces étapes, en tant que code Clojure :

(def x 0.000691M) ; the input number
(def p' 1) ; desired precision
(def s' (+ (.scale x) p' (- (.precision x)))) ; desired new scale
(.setScale x s' BigDecimal/ROUND_HALF_EVEN)
; 0.0007M

Je sais, c'est beaucoup d'étapes juste pour changer la précision !

Pourquoi BigDecimal ne fournit-il pas déjà cela ? Ai-je oublié quelque chose ?

4voto

E Hashmi Points 74
 BigDecimal decPrec = (BigDecimal)yo.get("Avg");
 decPrec = decPrec.setScale(5, RoundingMode.CEILING);
 String value= String.valueOf(decPrec);

De cette façon, vous pouvez définir la précision spécifique d'un BigDecimal .

La valeur de decPrec était 1.5726903423607562595809913132345426 qui est arrondi à 1.57267 .

0voto

Hakan Anlamaz Points 53

Essayez ce code ...

    Integer perc = 5;
    BigDecimal spread = BigDecimal.ZERO; 
    BigDecimal perc = spread.setScale(perc,BigDecimal.ROUND_HALF_UP);
    System.out.println(perc);

Résultat : 0.00000

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X