Gérer la précision et les problèmes potentiels
Lors de la conversion entre les types Long et double, vous devez être conscient de certains problèmes de précision et potentiels. Explorons-les en créant un dernier exemple.
Créer un programme pour démontrer les problèmes de précision
- Dans le WebIDE, accédez au répertoire
~/project/long-to-double
- Cliquez avec le bouton droit et sélectionnez "Nouveau fichier"
- Nommez le fichier
PrecisionDemo.java
Ajoutez le code suivant au fichier :
public class PrecisionDemo {
public static void main(String[] args) {
// 1. Precision loss with very large Long values
Long veryLargeLong = 9223372036854775807L; // Max Long value
double convertedDouble = veryLargeLong.doubleValue();
Long convertedBackToLong = (long) convertedDouble;
System.out.println("Original Long value: " + veryLargeLong);
System.out.println("Converted to double: " + convertedDouble);
System.out.println("Converted back to Long: " + convertedBackToLong);
System.out.println("Are they equal? " + veryLargeLong.equals(convertedBackToLong));
System.out.println("Difference: " + (veryLargeLong - convertedBackToLong));
System.out.println();
// 2. Scientific notation display
Long million = 1000000L;
double millionAsDouble = million.doubleValue();
System.out.println("Million as Long: " + million);
System.out.println("Million as double: " + millionAsDouble);
System.out.println("Million as double (with formatting): " + String.format("%.1f", millionAsDouble));
System.out.println();
// 3. Handling precision for financial calculations
Long centAmount = 123456789L;
double dollarAmount = centAmount / 100.0; // correct way
double incorrectDollarAmount = centAmount / 100; // potential issue (integer division)
System.out.println("Amount in cents: " + centAmount);
System.out.println("Correct dollar amount (cents/100.0): " + dollarAmount);
System.out.println("Incorrect dollar amount (cents/100): " + incorrectDollarAmount);
System.out.println();
}
}
Maintenant, compilons et exécutons ce programme :
cd ~/project/long-to-double
javac PrecisionDemo.java
java PrecisionDemo
Vous devriez voir une sortie similaire à :
Original Long value: 9223372036854775807
Converted to double: 9.223372036854776E18
Converted back to Long: 9223372036854775808
Are they equal? false
Difference: -1
Million as Long: 1000000
Million as double: 1000000.0
Million as double (with formatting): 1000000.0
Amount in cents: 123456789
Correct dollar amount (cents/100.0): 1234567.89
Incorrect dollar amount (cents/100): 1234567.89
Comprendre la précision et les problèmes potentiels
Voici les points clés de cette démonstration :
1. Perte de précision avec les très grands nombres
Notez que lorsque nous avons converti la valeur Long maximale en double et inversement, nous avons perdu de la précision :
- Valeur d'origine : 9223372036854775807
- Après conversion : 9223372036854775808
- Différence : -1
Cela se produit parce que double, bien qu'ayant une plage plus large, n'a pas suffisamment de précision pour représenter exactement toutes les valeurs Long possibles. Un double utilise 53 bits pour la mantisse (la partie qui stocke le nombre réel), tandis qu'un Long utilise 64 bits.
2. Affichage en notation scientifique
Les grands nombres au format double sont souvent affichés en notation scientifique (par exemple, 1.0E6 au lieu de 1000000). Il ne s'agit que d'un problème d'affichage, et non d'un problème de précision. Vous pouvez contrôler cela en utilisant le formatage.
3. Piège de la division entière
Lors de la division d'entiers en Java, le résultat est un entier. Pour obtenir un résultat décimal, au moins un opérande doit être un type à virgule flottante. Comparez :
- Correct :
centAmount / 100.0 (un opérande est un double)
- Problème potentiel :
centAmount / 100 (les deux opérandes sont des entiers)
Dans notre exemple spécifique, les valeurs sont les mêmes car nous travaillons déjà avec un double après la conversion de Long, mais c'est une erreur courante à surveiller.
Meilleures pratiques pour la conversion de Long en Double
-
Soyez conscient des limites de précision : Pour les très grandes valeurs Long, un double peut ne pas représenter exactement la même valeur.
-
Utilisez le formatage pour l'affichage : Contrôlez la façon dont les nombres sont affichés en utilisant des méthodes de formatage lorsque cela est nécessaire.
-
Envisagez d'utiliser BigDecimal pour les calculs financiers : Pour les applications financières de haute précision, envisagez d'utiliser BigDecimal au lieu de double.
-
Assurez-vous d'utiliser la division à virgule flottante : Assurez-vous qu'au moins un opérande est un type à virgule flottante lorsque vous avez besoin de résultats décimaux.