L’opérateur Modulo en Java

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 sont de typeint, le résultat de l'opération est un autreint:

@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 est de typefloat oudouble:

@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 de nombres entiers.

L'opérateur modulo nous donne exactement ce qui 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 égal à zéro.

La division et l’opération modulo lancent unArithmeticException lorsque nous essayons d’utiliser zéro comme opérande du côté droit:

@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 un nombre quelconque et deux est égal à un, il s’agit d’un nombre impair:

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

D'autre part, si le résultat est zéro (c'est-à-dire 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 spot libre dans un tableau circulaire.

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

Chaque fois que nous voulons placer un élément dans notre file d'attente circulaire, nous calculons simplement la position libre suivante en calculant le modulo du nombre d'éléments déjà insérés, plus 1, ainsi que 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êchonswriteIndex de tomber hors des limites du tableau, par conséquent, nous n'obtiendrons jamais unArrayIndexOutOfBoundsException.

Cependant, une fois que nous insérons plus deQUEUE_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 perdue autrement.

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 lesGitHub repository.