L'opérateur Modulo en Java

1. Vue d'ensemble

Dans ce court didacticiel, nous allons montrer ce qu'est l'opérateur modulo et comment nous pouvons l'utiliser avec Java pour certains cas d'utilisation courants.

2. L'opérateur Modulo

Commençons par les lacunes de la division simple en Java.

Si les opérandes des deux côtés de l'opérateur de division ont le type int , le résultat de l'opération est un autre int:

@Test public void whenIntegerDivision_thenLosesRemainder() { assertThat(11 / 4).isEqualTo(2); }

La même division nous donne un résultat différent lorsqu'au moins un des opérandes a le type float ou double:

@Test public void whenDoubleDivision_thenKeepsRemainder() { assertThat(11 / 4.0).isEqualTo(2.75); }

Nous pouvons observer que nous perdons le reste d'une opération de division lors de la division d'entiers.

L'opérateur modulo nous donne exactement ce reste:

@Test public void whenModulo_thenReturnsRemainder() { assertThat(11 % 4).isEqualTo(3); }

Le reste est ce qui reste après avoir divisé 11 (le dividende) par 4 (le diviseur) - dans ce cas, 3.

Pour la même raison, une division par zéro n'est pas possible, il n'est pas possible d'utiliser l'opérateur modulo lorsque l'argument de droite est zéro.

La division et l'opération modulo lancent une ArithmeticException lorsque nous essayons d'utiliser zéro comme opérande de droite:

@Test(expected = ArithmeticException.class) public void whenDivisionByZero_thenArithmeticException() { double result = 1 / 0; } @Test(expected = ArithmeticException.class) public void whenModuloByZero_thenArithmeticException() { double result = 1 % 0; }

3. Cas d'utilisation courants

Le cas d'utilisation le plus courant de l'opérateur modulo est de savoir si un nombre donné est pair ou impair.

Si le résultat de l'opération modulo entre n'importe quel nombre et deux est égal à un, c'est un nombre impair:

@Test public void whenDivisorIsOddAndModulusIs2_thenResultIs1() { assertThat(3 % 2).isEqualTo(1); }

Par contre, si le résultat est nul (c'est-à-dire qu'il n'y a pas de reste), c'est un nombre pair:

@Test public void whenDivisorIsEvenAndModulusIs2_thenResultIs0() { assertThat(4 % 2).isEqualTo(0); }

Une autre bonne utilisation de l'opération modulo est de garder une trace de l'indice du prochain point libre dans un tableau circulaire.

Dans une implémentation simple d'une file d'attente circulaire pour les valeurs int , les éléments sont conservés dans un tableau de taille fixe.

Chaque fois que nous voulons pousser un élément dans notre file d'attente circulaire, nous calculons simplement la prochaine position libre en calculant le modulo du nombre d'éléments que nous avons déjà insérés plus 1 et la capacité de la file d'attente:

@Test public void whenItemsIsAddedToCircularQueue_thenNoArrayIndexOutOfBounds() { int QUEUE_CAPACITY= 10; int[] circularQueue = new int[QUEUE_CAPACITY]; int itemsInserted = 0; for (int value = 0; value < 1000; value++) { int writeIndex = ++itemsInserted % QUEUE_CAPACITY; circularQueue[writeIndex] = value; } }

En utilisant l'opérateur modulo, nous empêchons writeIndex de tomber hors des limites du tableau, par conséquent, nous n'obtiendrons jamais une ArrayIndexOutOfBoundsException .

Cependant, une fois que nous insérons plus de QUEUE_CAPACITY éléments, l'élément suivant écrasera le premier.

4. Conclusion

L'opérateur modulo est utilisé pour calculer le reste d'une division entière qui serait autrement perdue.

Il est utile de faire des choses simples comme déterminer si un nombre donné est pair ou impair, ainsi que des tâches plus complexes comme le suivi de la prochaine position d'écriture dans un tableau circulaire.

L'exemple de code est disponible dans le référentiel GitHub.