Description du problème
Lorsque vous utilisez Java pour calculer les numéros de points flottants dans le projet, il a été constaté que pour des calculs comme 4.015 * 100, le résultat n'était pas le 401.5 attendu, mais 401.4999999999999999999999999994. Un si long nombre de chiffres est hostile pour l'affichage.
Cause du problème: représentation du nombre de points flottants
Après avoir consulté des informations pertinentes, j'ai constaté que la raison en est que les numéros de points flottants de l'ordinateur ne peuvent pas être entièrement exprimés avec précision. Par exemple, pour un double type 38414.4, l'ordinateur le stocke comme ceci:
Convertir en binaire: 100101100001110.0110011001100110011001100110011001100
Se transformer en sujet
Méthode de comptage d'apprentissage: 1.0010110000111001100110011001100110011001100110011001100110011001100 × 2 ^ 15
Le format à double codage est le suivant:
Bit à double signe 1 chiffre code de scène à 11 chiffres mantissa 52 chiffres
Bit de symbole: le nombre positif est 0
Code de commande: 15 est un nombre positif, donc le bit le plus élevé est 1, le bit le plus bas est moins 1, qui est 10000001110
MANTISSUE: Retirez la valeur par défaut 1 du bit le plus élevé, qui est 00101100001110011001100110011001100110011001100110000
Combiné, le codage final est: 0 1000001110 00101100001110011001100110011001100110011001100110011001100
De là, nous pouvons voir que la raison principale est que le codage binaire rend la partie fractionnaire impossible à exprimer pleinement exactement, comme 0,4 = 0,25 + 0,125 + ..., qui ne peut être fermée qu'infiniment. Par conséquent, des erreurs de précision se produiront lors du calcul des nombres de points flottants.
Solution: haute précision
BigDecimal en Java peut prendre en charge les opérations du numéro de point flottant avec une précision arbitraire. Dans le livre "Effective Java", il est recommandé que le flotteur et le double soient utilisés pour des calculs scientifiques ou des calculs d'ingénierie, tandis que Java.math.BigDecimal est utilisé dans les calculs commerciaux.
Il existe de nombreuses méthodes de construction pour BigDecimal, comme BigDecimal (Double) et BigDecimal (String). Il convient de noter que les paramètres de construction sont le type de chaîne pour garantir que la précision n'est pas perdue, car le double type lui-même est incomplètement précis. Par conséquent, il doit être écrit comme suit: BigDecimal ("0,02").
Les opérations de base de Double Type peuvent être trouvées dans BigDecimal. De plus, BigDecimal peut également être utilisé pour le formatage de sortie avec NumberFormat.
BigDecimal générera de nouveaux objets BigDecimal lorsque vous effectuez des opérations, il apportera donc plus de performances par rapport à Double.
Une étude préliminaire sur la mise en œuvre de haute précision
Alors, comment BigDecimal peut-il représenter une précision arbitraire? Voici seulement une analyse préliminaire.
Tout d'abord, examinons la mise en œuvre de BigInteger. Le type Int ordinaire est de 32 bits, il y a donc une limitation de portée. BigInteger a la variable de membre Int [] MAG, de sorte que le tableau INT plus long permet de représenter des entiers de toute taille.
Examinons la mise en œuvre de BigDecimal. Son introduction officielle indique que tout BigDecimal peut être représenté comme une échelle de valeur non échelle × 10 ^ -Scale. UNSCALEDVALUE est un entier de toute taille, correspondant à la variable membre BigInteger Intval dans le code source; L'échelle est l'ordre, correspondant à l'échelle INT de la variable dans le code source. De cette façon, BigDecimal est mis en œuvre sur la base de BigInteger.
Ce qui précède est la solution au problème de précision des points flottants dans Java présenté par l'éditeur. J'espère que cela vous sera utile. Si vous avez des questions, laissez-moi un message.