Qual è la sintassi per mod in Java


231

Ad esempio in pseudocodice:

if ((a mod 2) == 0)
{
    isEven = true;
}
else
{
    isEven = false;
}

Risposte:


357

Invece dell'operatore modulo, che ha una semantica leggermente diversa, per numeri interi non negativi, è possibile utilizzare l' operatore residuo% . Per il tuo esempio esatto:

if ((a % 2) == 0)
{
    isEven = true;
}
else
{
    isEven = false;
}

Questo può essere semplificato in una riga:

isEven = (a % 2) == 0;

80
L'if / se non è necessario, basta usare isEven = (a% 2) == 0,
— Steve Kuo,

59
Attento ai termini mod e modular perché n (mod m) È SEMPRE> = 0 ma non n% m. n% m è compreso nell'intervallo> -m e <m. Sebbene Java abbia un operatore residuo per i tipi int e long, non ha alcuna funzione o operatore modulo. Cioè, -12% 10 = -2 mentre -12 mod 10 = 8. Se l'operatore% restituisce un valore negativo per n% m, allora (n% m) + m ti darà n mod m. BigInteger fornisce funzioni per entrambi e le specifiche spiegano abbastanza bene la differenza. Inoltre, fai attenzione con zero. In matematica, mentre zero è un numero pari NON è positivo o negativo.
— Jim,

4
@ nl-x Probabilmente perché è meglio essere espliciti sulla precedenza piuttosto che lasciarlo alla convenzione. Io per primo non sapevo che %fosse valutato prima di ==cercarlo, quindi non sarebbe chiaro se l'espressione sia equivalente a (a%2)==0o a%(2==0). Immagino sia meno importante in Java dove un booleano non è uguale a un intero
— Matthew Sainsbury,

8
Questo non è l'operatore del modulo, è l'operatore residuo. Per favore correggi il post!
— Kieren Johnstone,

2
booleano even = ((a & 1) == 0). Molto più facile.
— mdev,

111

Ecco la rappresentazione del tuo pseudo-codice in un codice Java minimo;

boolean isEven = a % 2 == 0;

Ora lo scompongo nei suoi componenti. L'operatore del modulo in Java è il carattere percentuale (%). Pertanto, prendere un int% int restituisce un altro int. L'operatore double equals (==) viene utilizzato per confrontare valori, come una coppia di ints e restituisce un valore booleano. Questo viene quindi assegnato alla variabile booleana 'isEven'. In base alla precedenza dell'operatore, il modulo verrà valutato prima del confronto.


12
il minimo sarebbe senza parentesi;)
— pstanton,

3
È un operatore residuo, non un operatore modulo.
— Marchese di Lorne,

@ user207421 Il suo nome è in effetti operatore residuo ma non sono equivalenti: " modulo - 4. (elaborazione, programmazione) Un operatore posizionato tra due numeri, per ottenere il resto della divisione di quei numeri."?
— GeroldBroser ripristina Monica

93

Poiché tutti gli altri hanno già dato la risposta, aggiungerò un po 'di contesto aggiuntivo. % l'operatore "modulo" sta effettivamente eseguendo l'operazione rimanente. La differenza tra mod e rem è sottile, ma importante.

(-1 mod 2) normalmente darebbe 1. Più specificatamente dati due numeri interi, X e Y, l'operazione (X mod Y) tende a restituire un valore nell'intervallo [0, Y). Detto diversamente, il modulo di X e Y è sempre maggiore o uguale a zero e minore di Y.

L'esecuzione della stessa operazione con "%" o l'operatore rem mantiene il segno del valore X. Se X è negativo si ottiene un risultato nell'intervallo (-Y, 0]. Se X è positivo si ottiene un risultato nell'intervallo [0, Y).

Spesso questa sottile distinzione non ha importanza. Tornando alla domanda sul codice, tuttavia, ci sono diversi modi per risolvere "uniformità".

Il primo approccio è buono per i principianti, perché è particolarmente prolisso.

// Option 1: Clearest way for beginners
boolean isEven;
if ((a % 2) == 0)
{
  isEven = true
}
else
{
  isEven = false
}

Il secondo approccio sfrutta meglio il linguaggio e porta a un codice più conciso. (Non dimenticare che l'operatore == restituisce un valore booleano.)

// Option 2: Clear, succinct, code
boolean isEven = ((a % 2) == 0);

Il terzo approccio è qui per completezza e utilizza l' operatore ternario . Sebbene l'operatore ternario sia spesso molto utile, in questo caso considero superiore il secondo approccio.

// Option 3: Ternary operator
boolean isEven = ((a % 2) == 0) ? true : false;

Il quarto e ultimo approccio consiste nell'utilizzare la conoscenza di rappresentazione binaria di numeri interi . Se il bit meno significativo è 0, il numero è pari. Questo può essere verificato usando l' operatore bit-bit (&). Mentre questo approccio è il più veloce (stai facendo un semplice mascheramento dei bit invece della divisione), è forse un po 'avanzato / complicato per un principiante.

// Option 4: Bitwise-and
boolean isEven = ((a & 1) == 0);

Qui ho usato l'operatore bit per bit e l'ho rappresentato nella forma sintetica mostrata nell'opzione 2. La riscrittura nella forma dell'opzione 1 (e in alternativa dell'opzione 3) è lasciata come esercizio al lettore. ;)

Spero che aiuti.


Grazie Rob. Questa confusione causa enormi difficoltà a spiegare ai programmatori come implementare algoritmi con proprietà matematiche dall'aritmetica modulare. Il resto NON è un modulo ma si può derivare rapidamente un modulo dai resti.
— Jim,

1
@TickledPink Ad eccezione del fatto che questo non viene compilato in Java.
— Eugene Beresovsky

33

Per far funzionare l'operazione% (REM) di Java come MOD per valori X e Y positivi Y, è possibile utilizzare questo metodo:

private int mod(int x, int y)
{
    int result = x % y;
    if (result < 0)
    {
        result += y;
    }
    return result;
}

o con l'operatore ternario (più breve, ma non possibile o meno efficiente in alcune situazioni):

private int mod(int x, int y)
{
    int result = x % y;
    return result < 0? result + y : result;
}

12

Java in realtà non ha un operatore modulo come fa C. % in Java è un operatore rimanente. Sugli interi positivi, funziona esattamente come il modulo, ma funziona in modo diverso sugli interi negativi e, a differenza del modulo, può funzionare anche con numeri in virgola mobile. Tuttavia, è raro usare% su tutto tranne che sugli interi positivi, quindi se vuoi chiamarlo un modulo, sentiti libero!


Ma ne voglio uno un vero operatore modulo che funzioni anche per numeri interi negativi in ​​modo che array[x mod array.length]acceda sempre a un elemento nel mio array piuttosto che cercare di indicizzare posizioni negative.
— Kris

2
(x % y + y) % y o a partire da Java 8,Math.floorMod(x, y)
— Greg Charles,

12

Mentre è possibile fare un modulo corretto controllando se il valore è negativo e correggerlo se lo è (come molti hanno suggerito), esiste una soluzione più compatta.

(a % b + b) % b

Questo farà prima il modulo, limitando il valore all'intervallo -b -> + b, quindi aggiungendo b per garantire che il valore sia positivo, lasciando che il modulo successivo lo limiti all'intervallo 0 -> b.

Nota: se b è negativo, anche il risultato sarà negativo


Questo può traboccare quando aeb sono entrambi numeri grandi, quindi non è una soluzione corretta.
— Trixie Wolf,

11

Il codice funziona molto più velocemente senza usare modulo:

public boolean isEven(int a){
    return ( (a & 1) == 0 );
}

public boolean isOdd(int a){
    return ( (a & 1) == 1 );
}

3
Sembra molto più pulito della risposta accettata. Questo non ha nulla a che fare con l'ottimizzazione prematura. È semplicemente meglio, se funziona.
— AlexWien,

4
@LluisMartinez Questo è uno dei detti più citati nell'informatica. La citazione completa è "I programmatori sprecano enormi quantità di tempo pensando o preoccupandosi della velocità delle parti non critiche dei loro programmi, e questi tentativi di efficienza hanno effettivamente un forte impatto negativo quando si considerano il debug e la manutenzione. efficienze, dicono circa il 97% delle volte: l'ottimizzazione prematura è la radice di tutti i mali. Eppure non dovremmo rinunciare alle nostre opportunità in quel 3% critico ". Il che in realtà significa qualcosa di completamente diverso.
— Marchese di Lorne,

3
@EJP Probabilmente hai ragione. Ho fatto un test (loop con 1 milione di iterazioni) ho impiegato 4000 nanosecondi con modulo, 2500 nanosecondi con logico e.
— Lluis Martinez,

Perché questa dovrebbe essere una risposta? Sicuro che dispari anche, ma non fa nulla con l'operatore mod / remainder. La domanda parla dell'operatore mod, non di come trovare pari dispari.
— Mark Walsh,



4

In Java è l' %operatore: 15.17.3. Operatore residuo%

Nota che c'è anche floorModnella java.lang.Mathclasse che darà un risultato diverso da %per argomenti con segni diversi:

public static int floorMod​(int x, int y)


1
Eseguito l'upgrade, perché floorMod è un operatore 'modulo' migliore rispetto %a quando funziona correttamente anche quando l'argomento è negativo. Nessuna delle altre risposte è davvero corretta poiché presentano la dichiarazione di non responsabilità che% non è realmente modulo a meno che gli argomenti non siano positivi. In particolare, se si desidera mappare ogni numero intero su una posizione consecutiva in un array, allora array[floorMod(i, array.length)funziona correttamente anche se l'indice iva in territorio negativo. Non così con %.
— Kris

3

Inoltre, la mod può essere utilizzata in questo modo:

int a = 7;
b = a % 2;

bequivarrebbe a 1. Perché 7 % 2 = 1.


è probabilmente un errore usare operatori composti in un esempio per principianti e senza output.
— Stu Thompson,

3

L'operatore residuo in Java è %e l'operatore modulo può essere espresso come

public int mod(int i, int j)
{
  int rem = i % j;
  if (j < 0 && rem > 0)
  {
    return rem + j;
  }
  if (j > 0 && rem < 0)
  {
    return rem + j;
  }
  return rem;
}

2

Come altri hanno sottolineato, l' %operatore (resto) non è lo stesso moddell'operazione / funzione del modulo matematico .

mod vs %

La x mod nfunzione di mappe xper nla gamma di [0,n).
Considerando che l' x % noperatore di mappe xper nla gamma di (-n,n).

Per avere un metodo per usare l'operazione del modulo matematico e non preoccuparsi del segno davanti a xuno, puoi usare:

((x % n) + n) % n

Forse questa foto aiuta a capirla meglio (ho avuto difficoltà a avvolgere la mia testa per prima)

inserisci qui la descrizione dell'immagine


1
Bel disegno. Un'altra complessità: ciò non tiene conto della modularità 2 ^ 32 della intvariabile stessa. Il floorModmetodo lo fa correttamente (ma potresti aver bisogno di calcoli aggiuntivi se nè negativo).
— Maarten Bodewes,

1

Un altro modo è:

boolean isEven = false;
if((a % 2) == 0)
{
    isEven = true;
}

Ma il modo più semplice è ancora:

boolean isEven = (a % 2) == 0;

Come ha detto @Steve Kuo.


0

In Java, l' operazione mod può essere eseguita come tale:

Math.floorMod(a, b)

Nota: l' operazione mod è diversa dall'operazione rimanente . In Java, l' operazione rimanente può essere eseguita come tale:

a % b

Beh, non esattamente ... Il javadoc ce l' Math.floorMod()ha: The floor modulus is x - (floorDiv(x, y) * y), has the same sign as the divisor y, and is in the range of -abs(y) < r < +abs(y).Quindi non è esattamente lo stesso del modulo matematico. Ma c'è un modo per ottenere un risultato positivo, anche nel Javadoc dello stesso metodo:If the signs of arguments are unknown and a positive modulus is needed it can be computed as (floorMod(x, y) + abs(y)) % abs(y).
— WesternGun

@WesternGun Questo può essere vero, ma se sai che il modulo è positivo, l' floorModoperazione funziona come previsto. C'è anche il floorModper i longvalori e altrimenti c'è BigIntegerper i valori più grandi.
— Maarten Bodewes,

-1

L'operatore modulo è% (segno di percentuale). Per verificare l'uniformità o in generale fare modulo per una potenza di 2, puoi anche usare & (l'operatore e) come isEven =! (A & 1).


-3

Un'alternativa al codice di @Cody:

Utilizzando l'operatore modulo:

bool isEven = (a % 2) == 0;

Penso che questo sia un codice leggermente migliore rispetto alla scrittura if / else, perché c'è meno duplicazione e flessibilità inutilizzata. Richiede un po 'più di potenza cerebrale da esaminare, ma la buona denominazione di isEvencompensa.


2
È un operatore residuo, non un operatore modulo.
— Marchese di Lorne,

@EJP ok. Allora qual è l'operatore del modulo?
— TheRealChx101
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.