Réglez tous les BigDecimal opérations à une certaine précision?
Mon programme Java est centrée autour de la haute précision des calculs, qui ont besoin d'être précis à au moins 120 décimales.
Par voie de conséquence, tous des nombres non-entiers seront représentés par BigDecimals dans le programme.
Évidemment j'ai besoin de spécifier la précision de l'arrondi de la BigDecimals, pour éviter décimal infini expressions, etc.
Actuellement, je trouve ça un énorme nuisance à avoir à spécifier la précision à chaque instanciation ou opération mathématique d'un BigDecimal.
Est-il un moyen de définir un mondial de précision pour tous les BigDecimal calculs?
(Comme le Context.prec()
pour la Décimal module en python)
Grâce
Caractéristiques:
Java jre7 SE
Windows 7 (32)
OriginalL'auteur Anti Earth | 2012-04-08
Vous devez vous connecter pour publier un commentaire.
(Presque) D'Origine
Pas aussi simple, mais vous pouvez créer un
MathContext
et de le transmettre à tous vosBigDecimal
les constructeurs et les méthodes d'exécution des opérations.Révisé
Alternativement, vous pouvez étendre
BigDecimal
et remplacer toutes les opérations que vous souhaitez utiliser en fournissant le droitMathContext
, et à l'aide de l'arrondissement à la version dedivide
:Je suis effectivement d'avoir des difficultés à utiliser l'extension de classe. Si j'ai 2 BigDecimals représentant "1" et "3", qui ont tous deux fixés à 120... Division "1" par "3" produit toujours un non-terminaison virgule, même si j'en affecter le résultat d'une échelle de 120! (Qui est ce que j'ai été à l'origine d'essayer de les éviter; des paramètres supplémentaires pour des opérations mathématiques).
Je pense que vous pouvez corriger cela en même substitution de la
divide
méthode pour votre classe.C'est en essayant d'être aussi exact que possible, ce qui signifie essayer de ne jamais tour, à moins que demandé. Le fossé remplacement est simple, vous devez juste wrap de l'arrondissement
divide
. Maintenant que j'y pense, ce serait une bonne idée pour remplacer d'autres activités sont l'aide à s'assurer qu'ils sont de retour d'une instance de votre classe et n'est pas régulierBigDecimal
.Malheureusement, vous aurez toujours besoin de la superclasse le constructeur si vous souhaitez utiliser un
number.divide(otherNumber);
syntaxe, parce que vous avez besoinnumber
pour être de typeMyBigDecimal
et pasBigDecimal
. Une autre option est de simplement oublier de sous-classement et d'écrire unstatic BigDecimal divide( BigDecimal a, BigDecimal b ){ a.divide(b,context);};
de la fonction et de l'utiliser à la place de celui fourni.OriginalL'auteur trutheality
Créer un
BigDecimalFactory
classe statique usine méthodes correspondant à tous les constructeurs qui acceptentMathContext
- sauf que lesMathContext
instance est à l'intérieur de l'usine et de manière statique initialisé au moment du démarrage. Voici un fragment:MathContext
pour la conversion. Il n'est pas attaché à laBigDecimal
objet.Cela signifie que la précision de la contrainte ne s'appliquent pas aux opérations effectuées sur le
BigDecimal
des instances créées avec l'usine ... à moins que vous offre laMathContext
comme un argument à l'opération concernée.Argh! Vous avez raison. Je l'ai mentionné vos commentaires dans l'une des autres threads dans ce post, afin que les gens sachent.
OriginalL'auteur sparc_spread
Pas.
Vous aurez à créer une classe wrapper qui a un
MathContext
comme un attribut supplémentaire. Il sera nécessaire de:utiliser cette
mc
pour chaque opération mathématique qui serait autrement utiliser la valeur par défaut de la sémantique, etde créer et de revenir un autre enveloppé exemple à chaque fois que le enveloppés opération retourne régulièrement instance.
(Une variante, vous pouvez mettre en place une "global"
MathContext
à l'aide d'un statique, mais vous aurez toujours besoin d'utiliser wrappering pour s'assurer que lemc
est utilisé.)(Extension de
BigDecimal
serait trop de travail, et qui est défendable plus lisible qu'une classe wrapper.)Vous dit dans un commentaire:
(Questions de conception ne peut être répondu définitivement par l'équipe de conception. Cependant ...)
Comme avec tous les complexes de l'utilitaire de classes, la conception de BigDecimal est un compromis qui est conçu pour répondre aux exigences d'un large éventail de cas d'utilisation. C'est aussi un compromis entre les différentes méta-exigences (mauvais mot) de "puissance d'utilisation" et "simplicité".
Ce que vous avez est un cas d'utilisation qui n'est pas particulièrement bien pris en charge. Mais je pense que si il a été bien pris en charge (par exemple, avec un
MathContext
le contrôle de tout ou d'uneMathContext
attaché à chaqueBigDecimal
) alors ce serait introduire toutes sortes d'autres complexités; par exemple, en traitant avec les opérations où il y a deux ou plusieurs concurrents contexte des objets à prendre en compte. Ces problèmes pourraient être traités ... mais elles sont susceptibles de conduire à des "surprises" pour le programmeur, et qui n'est pas une bonne chose.L'approche actuelle est simple et facile à comprendre, et si vous avez besoin de quelque chose de plus compliqué, vous pouvez la mettre en œuvre ... explicitement à la fourniture d'une
MathContext
pour les activités qui le nécessitent.OriginalL'auteur Stephen C
Vous pouvez créer une classe qui étend la classe
BigDecimal
et détermine la précision automatiquement pour vous. Alors vous utilisez vous cette classe.Cela ne marchera pas. À partir de la documentation Javadoc sur "setScale': "à Noter que depuis BigDecimal objets sont immuables, les appels de cette méthode ne se traduisent pas dans l'objet d'origine en cours de modification, contrairement à la convention de méthodes nommé setX muter champ X. au Lieu de cela, setScale retourne un objet avec la bonne échelle; le retour de l'objet peut ou peut ne pas être nouvellement affectés." Afin de l'appelant dans le constructeur ne fait rien, au moins dans certaines situations.
OriginalL'auteur twain249
Vous pouvez créer un wrapper pour BigDecimals, qui va faire ce travail:
Dans ce cas, vous n'avez pas à remplacer toutes les opérations de BigDecimal (dans l'extension des cas), juste ceux que vous utilisez. Il vous donne le contrôle sur toutes les instances et ne force pas à suivre BigDecimal contrat.
OriginalL'auteur Eugene Retunsky
Vous devrez créer votre propre classe wrapper qui a par défaut de votre MathContext comme cette exemple:
Dans cet exemple, j'ai utilisé la bibliothèque (https://projectlombok.org)
Test:
OriginalL'auteur rafambbr
Vous pouvez utiliser le BigDecimal setScale fonction!
OriginalL'auteur Kevin