1. Introduction
Pour emprunter les mots au livre "Effactive Java", les principaux objectifs de conception des types de flottants et de doubles sont destinés à l'informatique scientifique et à l'informatique d'ingénierie. Ils effectuent des opérations de points flottants binaires, qui sont soigneusement conçus pour fournir une approximation rapide plus précise sur la gamme numérique de grande région. Cependant, ils ne fournissent pas de résultats complètement précis et ne doivent pas être utilisés dans des situations où des résultats précis sont nécessaires. Cependant, les calculs commerciaux nécessitent souvent des résultats précis, et BigDecimal est utile pour le moment.
2. Introduction à BigDecimal
BigDecimal se compose d'une valeur entière non à l'échelle de toute précision et d'une échelle entière 32 bits. S'il est nul ou positif, l'échelle est le nombre de chiffres après le point décimal. S'il s'agit d'un nombre négatif, multipliez la valeur de non-échelle du nombre par une puissance d'échelle négative de 10. Par conséquent, la valeur représentée par BigDecimal est (UNSCALEDVALUE × 10-échelle).
3. Code de test
3.1 Constructeur (les principaux types de paramètres de test sont deux constructeurs communs avec double et chaîne)
La copie de code est la suivante: bigdecimal adouble = new BigDecimal (1.22);
System.out.println ("Construire avec une double valeur:" + adouble);
Bigdecimal astring = new Bigdecimal ("1.22");
System.out.println ("Construire avec une valeur de chaîne:" + astrring);
Selon vous, quelle sera la sortie? Si vous ne pensez pas que le premier sortira 1.22, alors félicitations pour la réponse correctement, le résultat de sortie est le suivant:
Copiez le code comme suit: Construire avec une double valeur: 1.2199999999999999999733546474089962430298328399658203125
Construire avec une valeur de chaîne: 1.22
Description de JDK:
1. Les résultats de la méthode de construction avec le type de paramètre double sont imprévisibles. Certaines personnes pourraient penser que le BigDecimal créé en écrivant NewBigDecimal (0,1) en Java est exactement égal à 0,1 (valeur non échelle 1, dont l'échelle est 1), mais elle est en fait égale à 0,10000000000000000000005551115123125782702118158404541015625. En effet, 0,1 ne peut pas être exprimé avec précision comme un double (ou pour ce cas, il ne peut pas être exprimé en toute décimale binaire de longueur finie). De cette façon, la valeur transmise dans la méthode de construction ne sera pas exactement égale à 0,1 (bien qu'elle soit sur une surface égale à cette valeur).
2. D'un autre côté, la méthode de construction de cordes est complètement prévisible: l'écriture sur NewBigDecimal ("0,1") créera un BigDecimal, ce qui est exactement égal au 0,1 attendu. Par conséquent, en comparaison, il est généralement recommandé d'utiliser d'abord le constructeur de chaîne.
3. Lorsque le double doit être utilisé comme source de BigDecimal, veuillez noter que ce constructeur fournit une conversion précise; Il ne fournit pas le même résultat que les opérations suivantes: utilisez d'abord la méthode double.tostring (double), puis utilisez le constructeur BigDecimal (String) pour convertir le double en chaîne. Pour obtenir le résultat, utilisez la méthode de valeur statique (double).
3.2 Opération d'ajout
La copie de code est la suivante: bigdecimal a = new BigDecimal ("1.22");
System.out.println ("Construire avec une valeur de chaîne:" + a);
BigDecimal B = nouveau BigDecimal ("2.22");
a.add (b);
System.out.println ("Aplus B est:" + a);
Il est facile de penser qu'il sortira:
Copiez le code comme suit: Construire avec une chaîne de string: 1.22
A plus B est: 3,44
Mais en fait, un plus B est: 1,22
4. Analyse du code source
4.1 Valeur de la méthode (doubleval)
Copiez le code comme suit: Valeur bigdecimale statique publique (double val) {
// Rappel: un double retour «0,0».
// pour utiliser le zéro constant. Cela pourrait être assez important pour
// justifient une approche d'usine, un cache ou quelques
// Constantes, plus tard.
retournew bigdecimal (double.tostring (val)); // voir le troisième point en 3.1 sur la description JDK
}
4.2 Méthode Ajouter (BigDecimal Augrend)
public bigdecimal add (BigDecimal Augrend) {long xs = this.intcompact; // BigDecimal représenté par un nombre entier, par exemple A a une valeur intcompact de 122 long ys = Augend.intCompact; // identique à BigInteger fst = (this.intcompact! = Flay ! = Gonflé)? Null: Augend.intval; int rscale = this.scale; // les décimaux Long Sdiff = (long) rscale - Augend.scale; // la différence entre décimales if (sdiff! = 0) {// Les décimaux avec les plus décimaux sont le résultat if (sdiff <0) {int releving = checkscale (-sdiff); RSCALE = ungend.scale; if (xs == gonflé || (xs = longMultiplyPower (xs, augmentation)) == Flat) fst = bigMultiplyPower (augmentation); } else {int asingl = ungend.checkScale (sdiff); if (ys == gonflé || (ys = longMultiplyPowerTen (ys, relance)) == gonflé) snd = augend.bigmultiplypower (augmentation); }} if (xs! = fléchissement && ys! = gonflé) {long sum = xs + ys; if ((((sum ^ xs) & (sum ^ ys)))> = 0l) // juger s'il y a un débordement. Retour BigDecimal.ValueOf (SUM, RCALE); // RETOUR BIGDECIMAL INSTERNE obtenu en utilisant la méthode d'usine statique de BigDecimal} if (fst == null) fst = bigInteger.valueof (xs); // BigInteger's Static Factory Method if (snd == null) snd = bigInteger.Valueof (ys); BigInteger sum = fst.add (snd); return (fst.signum == snd.signum)? new BigDecimal (sum, gonflé, rcale, 0): new BigDecimal (sum, compactvalfor (sum), rcal, 0); // retourne l'objet BigDecimal obtenu par d'autres méthodes de construction}Ce qui précède n'est qu'une analyse du code source d'addition. La soustraction, la multiplication et la division renvoient en fait un nouvel objet BigDecimal. Parce que BigInteger et BigDecimal sont tous deux immuables, un nouvel objet sera généré lors de la réalisation de chaque étape de fonctionnement, donc a.Add (b); Bien que l'opération d'addition soit effectuée, A n'enregistre pas la valeur après l'opération d'addition. L'utilisation correcte doit être a = a.add (b);
5. Résumé
(1) Les calculs commerciaux utilisent BigDecimal.
(2) Essayez d'utiliser des constructeurs avec une chaîne de type de paramètre.
(3) Les BigDecimaux sont immuables. Lorsque vous effectuez chaque étape de fonctionnement, un nouvel objet sera généré. Par conséquent, lors de l'addition, de la soustraction, de la multiplication et de la division, vous devez enregistrer la valeur après l'opération.
(4) Nous avons souvent tendance à ignorer certains détails de mise en œuvre du JDK sous-jacent, ce qui entraîne des erreurs, nous devons donc prêter plus d'attention.
Référence: classe BigDecimal