Operatorul Modulo în Java

1. Prezentare generală

În acest scurt tutorial, vom arăta ce este operatorul modulo și cum îl putem folosi cu Java pentru unele cazuri de utilizare obișnuite.

2. Operatorul Modulo

Să începem cu deficiențele diviziunii simple în Java.

Dacă operanzii de pe ambele părți ale operatorului de divizare au tipul int , rezultatul operației este un alt int:

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

Aceeași diviziune ne oferă un rezultat diferit atunci când cel puțin unul dintre operanzi are tip float sau dublu:

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

Putem observa că pierdem restul unei operații de divizare atunci când împărțim numere întregi.

Operatorul modulo ne oferă exact acest rest:

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

Restul este ceea ce rămâne după împărțirea a 11 (dividendul) la 4 (divizorul) - în acest caz, 3.

Din același motiv, o împărțire la zero nu este posibilă, nu este posibil să utilizați operatorul modulo atunci când argumentul din partea dreaptă este zero.

Atât operația de divizare, cât și operația modulo aruncă o ArithmeticException când încercăm să folosim zero ca operand din partea dreaptă:

@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. Cazuri de utilizare frecvente

Cel mai frecvent caz de utilizare pentru operatorul modulo este de a afla dacă un număr dat este impar sau par.

Dacă rezultatul operației modulo între orice număr și doi este egal cu unul, este un număr impar:

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

Pe de altă parte, dacă rezultatul este zero (adică nu există rest), este un număr par:

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

O altă utilizare bună a operației modulo este de a urmări indicele următorului loc liber într-o matrice circulară.

Într-o implementare simplă a unei cozi circulare pentru valorile int , elementele sunt păstrate într-o matrice de dimensiuni fixe.

De fiecare dată când dorim să împingem un element în coada noastră circulară, calculăm următoarea poziție liberă calculând modulul numărului de elemente pe care le-am inserat deja plus 1 și capacitatea cozii:

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

Folosind operatorul modulo împiedicăm writeIndex să cadă în afara limitelor matricei, prin urmare, nu vom obține niciodată o excepție ArrayIndexOutOfBoundsException .

Cu toate acestea, odată ce inserăm mai mult de QUEUE_CAPACITY articole, următorul articol îl va suprascrie pe primul.

4. Concluzie

Operatorul modulo este folosit pentru a calcula restul unei divizii întregi care altfel s-a pierdut.

Este util să faceți lucruri simple, cum ar fi să aflați dacă un anumit număr este par sau impar, precum și sarcini mai complexe, cum ar fi urmărirea următoarei poziții de scriere într-o matrice circulară.

Exemplul de cod este disponibil în depozitul GitHub.