Existe-t-il une différence entre les opérations effectuées par Java à l'aide d'opérateurs de raccourci par rapport aux opérateurs classiques?
-
05-07-2019 - |
Question
Je travaille sur un programme Java concernant le triangle de Pascal.
Voici comment cela est codé:
for(int i = 0; i < 5; i++){
for(int j = 0, x = 1; j <= i; j++){
System.out.print(x + " ");
x = x * (i - j) / (j + 1);
}
System.out.println();
}
et cela montre:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
Mais quand j'ai essayé de changer le code en:
for(int i = 0; i < 5; i++){
for(int j = 0, x = 1; j <= i; j++){
System.out.print(x + " ");
x *= (i - j) / (j + 1);
}
System.out.println();
}
et comme vous l'avez peut-être remarqué, seul l'opérateur a changé en * =, mais le résultat est:
1
1 1
1 2 0
1 3 3 0
1 4 4 0 0
Avez-vous une idée de ce qui s’est passé? Merci d'avance!
La solution
C'est parce que vous utilisez l'arithmétique des nombres entiers dans le mauvais ordre.
x *= (i - j) / (j + 1);
est identique à
x = x * ((i - j) / (j + 1));
Les crochets sont importants. (i - j) / (j + 1)
est dans la plupart des cas pas un nombre entier, mais Java le arrondit quand même à un entier.
La façon dont vous l'avez fait en premier
x = x * (i - j) / (j + 1);
la multiplication se produit avant la division, de sorte que vous n'obtenez aucune erreur d'arrondi.
Autres conseils
Vous avez remplacé la haute priorité * par une basse priorité * =, ce qui a entraîné
x = x * ((i - j) / (j + 1));
au lieu de
x = (x * (i - j)) / (j + 1);
que vous avez probablement voulu.
Ressemble à la division entière par rapport à l'ordre des opérations. Ajoutez des parenthèses et vous obtiendrez les mêmes résultats. Si vous divisez les 2/3 en nombres entiers, vous obtenez 0. Il est donc important de multiplier en premier.