while (x != y) { if (x > y) { x = x-y; } else { y = y-x; } }
Contrairement au for de l'exemple précédent, il n'est pas évident que cette boucle termine2.1, c'est-à-dire qu'il n'y ait qu'un nombre fini d'itérations. En effet si 61#61 ou 62#62 est 72#72, la boucle ne termine pas. Supposons que 73#73 et 74#74 ; après initialisation, on a donc 75#75 et 76#76; à chaque itération, si 77#77, 78#78 décroît strictement, mais reste strictement positif. Il y a donc au plus 79#79 itérations avant que la condition ne devienne fausse, c'est-à-dire que 64#64. Ce n'est pas très efficace.
Tout en conservant le même invariant
63#63, on peut choisir
d'autres transformations de x et y de sorte que la
boucle termine en moins d'itérations ; c'est l'algorithme d'Euclide
dans sa version moderne, où l'on remplace la soustraction par le calcul
du reste par division entière (opérateur %
), en utilisant
l'identité
80#80 ; voici ce que donne
directement ce remplacement :
while (x != y) { if (x > y) { x = x%y; } else { y = y%x; } }
Comme 81#81, les tests peuvent être éliminés en faisant en sorte que la valeur de x soit supérieure à celle de y.
static int pgcd(int x, int y) { while (y > 0) { int t = x%y; x = y; y = t; } return x; }Rappelons que les arguments étant passés par valeur, les affectations aux paramètres x et y ne modifient que des variables locales et en aucune façon les arguments eux-mêmes.