L'operatore Modulo in Java

1. Panoramica

In questo breve tutorial, mostreremo cos'è l'operatore modulo e come possiamo usarlo con Java per alcuni casi d'uso comuni.

2. L'operatore Modulo

Cominciamo con le carenze della semplice divisione in Java.

Se gli operandi su entrambi i lati dell'operatore di divisione hanno tipo int , il risultato dell'operazione è un altro int:

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

La stessa divisione ci dà un risultato diverso quando almeno uno degli operandi è di tipo float o double:

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

Possiamo osservare che perdiamo il resto di un'operazione di divisione quando dividiamo interi.

L'operatore modulo ci fornisce esattamente questo resto:

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

Il resto è ciò che rimane dopo aver diviso 11 (il dividendo) per 4 (il divisore), in questo caso 3.

Per lo stesso motivo non è possibile una divisione per zero, non è possibile utilizzare l'operatore modulo quando l'argomento a destra è zero.

Sia la divisione che l'operazione modulo generano un'eccezione ArithmeticException quando stiamo cercando di utilizzare zero come operando sul lato destro:

@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. Casi d'uso comuni

Il caso d'uso più comune per l'operatore modulo è scoprire se un dato numero è pari o dispari.

Se il risultato dell'operazione modulo tra un numero qualsiasi e due è uguale a uno, è un numero dispari:

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

D'altra parte, se il risultato è zero (cioè non c'è resto), è un numero pari:

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

Un altro buon uso dell'operazione modulo è tenere traccia dell'indice del successivo punto libero in una matrice circolare.

In una semplice implementazione di una coda circolare per valori int , gli elementi vengono conservati in un array di dimensioni fisse.

Ogni volta che vogliamo inserire un elemento nella nostra coda circolare, calcoliamo semplicemente la successiva posizione libera calcolando il modulo del numero di elementi che abbiamo già inserito più 1 e la capacità della coda:

@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; } }

Usando l'operatore modulo impediamo a writeIndex di uscire dai limiti dell'array, quindi non avremo mai un'eccezione ArrayIndexOutOfBoundsException .

Tuttavia, una volta inseriti più di QUEUE_CAPACITY elementi, l'elemento successivo sovrascriverà il primo.

4. Conclusione

L'operatore modulo viene utilizzato per calcolare il resto di una divisione intera che altrimenti andrebbe persa.

È utile fare cose semplici come capire se un dato numero è pari o dispari, così come attività più complesse come tracciare la successiva posizione di scrittura in una matrice circolare.

Il codice di esempio è disponibile nel repository GitHub.