Modulo-operatøren i Java

1. Oversikt

I denne korte opplæringen skal vi vise hva modulooperatøren er, og hvordan vi kan bruke den med Java for noen vanlige brukssaker.

2. Modulo-operatøren

La oss starte med manglene ved enkel deling i Java.

Hvis operandene på begge sider av divisjonsoperatøren har type int, resultatet av operasjonen er et annet int:

@Test offentlig ugyldig nårIntegerDivision_thenLosesRemainder () {assertThat (11/4) .isEqualTo (2); }

Den samme divisjonen gir oss et annet resultat når minst en av operandene har type flyte eller dobbelt:

@Test offentlig ugyldig nårDoubleDivision_thenKeepsRemainder () {assertThat (11 / 4.0) .isEqualTo (2.75); }

Vi kan se at vi mister resten av en divisjonsoperasjon når vi deler heltall.

Moduloperatøren gir oss nøyaktig denne resten:

@Test offentlig ugyldig nårModulo_thenReturnsRemainder () {assertThat (11% 4) .isEqualTo (3); }

Resten er det som gjenstår etter å ha delt 11 (utbyttet) med 4 (deleren) - i dette tilfellet 3.

Av samme grunn er det ikke mulig å dele med null, og det er ikke mulig å bruke modulo-operatøren når argumentet til høyre er null.

Både delingen og moduloperasjonen kaster en Aritmetisk unntak når vi prøver å bruke null som operand på høyre side:

@Test (forventet = ArithmeticException.class) offentlig ugyldig nårDivisionByZero_thenArithmeticException () {dobbelt resultat = 1/0; } @Test (forventet = ArithmeticException.class) offentlig ugyldig nårModuloByZero_thenArithmeticException () {dobbelt resultat = 1% 0; }

3. Vanlige brukstilfeller

Det vanligste bruksområdet for modulo-operatøren er å finne ut om et gitt tall er oddetall eller jevnt.

Hvis utfallet av moduloperasjonen mellom et tall og to er lik ett, er det et oddetall:

@Test offentlig ugyldig nårDivisorIsOddAndModulusIs2_thenResultIs1 () {assertThat (3% 2) .isEqualTo (1); }

På den annen side, hvis resultatet er null (dvs. det er ingen rest), er det et partall:

@Test offentlig ugyldig nårDivisorIsEvenAndModulusIs2_thenResultIs0 () {assertThat (4% 2) .isEqualTo (0); }

En annen god bruk av moduloperasjonen er å holde oversikt over indeksen til neste ledige punkt i en sirkulær matrise.

I en enkel implementering av en sirkulær kø for int verdier, holdes elementene i en matrise med fast størrelse.

Hver gang vi vil skyve et element til den sirkulære køen vår, beregner vi bare neste ledige posisjon ved å beregne modulo for antall elementer vi allerede har satt inn pluss 1 og køkapasiteten:

@Test offentlig ugyldig nårItemsIsAddedToCircularQueue_thenNoArrayIndexOutOfBounds () {int QUEUE_CAPACITY = 10; int [] circularQueue = ny int [QUEUE_CAPACITY]; int itemsInserted = 0; for (int verdi = 0; verdi <1000; verdi ++) {int writeIndex = ++ itemsInserted% QUEUE_CAPACITY; circularQueue [writeIndex] = verdi; }}

Ved å bruke modulo-operatøren forhindrer vi writeIndex for å falle ut av grensen til matrisen, får vi derfor aldri en ArrayIndexOutOfBoundsException.

Imidlertid, når vi setter inn mer enn QUEUE_CAPACITY elementer, vil neste element overskrive det første.

4. Konklusjon

Moduloperatøren brukes til å beregne resten av en heltallsdeling som ellers mistet.

Det er nyttig å gjøre enkle ting som å finne ut om et gitt tall er jevnt eller merkelig, samt mer komplekse oppgaver som å spore neste skriveposisjon i et sirkulært utvalg.

Eksempelkoden er tilgjengelig i GitHub-depotet.