J'ai récemment étudié les problèmes de calcul à virgule flottante de Java, recherché des informations pertinentes sur Internet, résumé et effectué un tri et un débogage, et finalement terminé cet article. Tout le monde est invité à signaler les erreurs et les problèmes.
En Java, les variables déclarées par float sont des nombres à virgule flottante simple précision, et les variables déclarées par double sont des nombres à virgule flottante double précision. Comme leur nom l'indique, les entités de type double occupent deux fois l'espace mémoire de float. float fait 4 octets et double fait 8 octets. Les données de type float et double ne peuvent pas représenter avec précision les résultats des calculs. En effet, float et double sont des calculs imprécis. Vous pouvez le voir à travers le code suivant :
Copiez le code comme suit :
Test de classe publique
{
public static void main (String[] arguments)
{
System.out.println(0,05 + 0,01);
System.out.println(1.0 - 0.42);
System.out.println(4.015 * 100);
System.out.println(123,3/100);
}
}
Le résultat de la course est :
0,060000000000000005
0,5800000000000001
401.49999999999994
1.232999999999999999
Pour obtenir l'effet souhaité, nous pouvons essayer d'utiliser java.text.DecimalFormat pour formater les nombres à virgule flottante :
DecimalFormat peut formater les nombres selon un certain format. Les caractères de formatage couramment utilisés sont #, 0, etc. exemple:
Copiez le code comme suit :
System.out.println(new java.text.DecimalFormat("0.00").format(3.125));
System.out.println(new java.text.DecimalFormat("0.00").format(3.135));
Mais le résultat est :
3.12
3.14
En effet, DecimalFormat utilise un arrondi demi-pair (ROUND_HALF_EVEN. En termes simples, il s'appuie sur le nombre pair le plus proche pour arrondir à 5). Par conséquent, des nombres à virgule flottante fiables ne peuvent pas être obtenus à l’aide de DecimalForamt. Enfin on peut envisager d'utiliser BigDecimal pour des calculs plus précis :
BigDecimal fournit plusieurs constructeurs, liés aux nombres à virgule flottante :
Copiez le code comme suit :
BigDecimal(double val) Traduit un double en BigDecimal.
BigDecimal(String val) Traduit la représentation String d'un BigDecimal en BigDecimal.
Cependant, l'utilisation de paramètres doubles pour créer des objets entraînera des valeurs inexactes. Seule la création d'objets via String est la plus précise.
Par exemple:
Copiez le code comme suit :
BigDecimal bd1=nouveau BigDecimal(0,05);
System.out.println(bd1.toString());
BigDecimal bd2=nouveau BigDecimal("0.05");
System.out.println(bd2.toString());
Obtenez le résultat :
0.05000000000000000277555756156289135105907917022705078125
0,05
Par conséquent, nous devons finalement utiliser String pour créer des objets, afin que les résultats obtenus soient les plus précis. De plus, s'il s'agit d'un nombre double, on peut également utiliser : BigDecimal.valueOf(double val). La raison est très simple. Le code source du JDK est le suivant :
Copiez le code comme suit :
public static BigDecimal valueOf (double val)
{
return new BigDecimal(Double.toString(val));
}
La dernière chose à noter est la suivante : l'addition, la soustraction, la multiplication et la division de BigDecimal renvoient finalement un nouvel objet BigDecimal. Parce que BigDecimal est immuable, un nouvel objet sera généré à chaque opération, donc un .add(b); est effectué, a n'enregistre pas la valeur après l'opération d'addition. L'utilisation correcte doit être a=a.add(b).