Come si stabilisce se un numero è pari o dispari?
In matematica, qualsiasi numero intero è o pari o dispari. Se è un multiplo di due, è un numero pari, altrimenti, è un numero dispari. Esempi di numero pari sono: -4, 0, 8 e 70. Esempi di numero dispari sono -5, 1 e 71. (fonte Wikipedia)
La teoria ci insegna quindi che se un numero intero è divisibile per 2 allora è pari, altrimenti è dispari.
Come si fa a vedere se un numero è divisibile per 2? La risposta è: dividiamo il numero per 2, se dà resto 0 allora il numero è divisibile per due.
Questa operazione molto semplice, nasconde qualche sorpresina che vale la pena discutere.
Consideriamo l’operazione aritmetica della divisione. Essa può essere rappresentata in questo modo:
Se N è il numero incriminato che dobbiamo dividere per 2 allora
R=N-(Q*2)
dove R è il resto della divisione di N per 2 e Q il quoziente
Esempio:
per N=23
N diviso 2 fa 11 con il resto di 1.
Cioè Q=11 e quindi R=23-(11*2)=23-22=1
Quindi N è dispari
In Java:
int n=23; /* IL NUMERO DA CONTROLLARE */ /* LA TEORIA DICE CHE IL RESTO DELLA DIVISIONE PER DUE DEVE ESSERE 0 PER I NUMERI PARI */ /* PRIMA SOLUZIONE */ System.out.println("PRIMA SOLUZIONE"); int quoziente=n/2; /* divisione intera */ int resto1=n-quoziente*2; if(resto1==0) { System.out.println(n +" E' NUMERO PARI"); } else { System.out.println(n +" E' NUMERO DISPARI"); }
NB:
Ora se guardiamo l’operazione:
int quoziente=n/2;
poichè n è intero e quoziente s’aspetta un intero, l’operazione di divisione “/” viene calcolata come un’operazione intera (senza virgola per capirci).
Ovviamente questa soluzione in termini di tempo risulta essere la più dispendiosa possibile. Molti di voi avranno già pensato: “Perché non usare l’operatore modulo % ?”
Beh si e quindi ecco la seconda versione:
/* SECONDA SOLUZIONE */ System.out.println("SECONDA SOLUZIONE"); int resto2= n % 2; if(resto2==0) { System.out.println(n +" E' NUMERO PARI"); } else { System.out.println(n +" E' NUMERO DISPARI"); }
Qualcuno più sveglio però saprà anche che se pensiamo alla rappresentazione in binario dei numeri interi questi hanno una caratteristica ancor più simpatica:
il bit con peso 2 elevato a 0 compare una volta 0 ed una volta 1.
Esempio rappresentiamo i primi 8 numeri da 1 a 8 in binario (su 4 bits)
0001
0010
0011
0100
0101
0110
0111
1000
Noterete che la cifre in grassetto si alternano in un balletto di zero e uno.
A questo punto ci viene in soccorso l’operatore logico AND che nello specifico si rappresenta con &
In pratica se ad un numero applichiamo l’operazione “N and 1” (in Java: n & 1) in pratica stiamo verificando se l’ultimo bit (il primo se guardiamo da destra) è 0 oppure 1, basandoci sulla legge che
se a e b sono due bit
a & b == 1 se e solo se a==1 e b==1
Per cui la nostra terza soluzione:
/* TERZA SOLUZIONE */ System.out.println("TERZA SOLUZIONE"); int resto3= n & 1; if(resto3==0) { System.out.println(n +" E' NUMERO PARI"); } else { System.out.println(n +" E' NUMERO DISPARI"); }
Vi chiederete: “Un post per calcolare se un numero è pari o dispari? Ci stai offendendo?”
No in realtà mi è capitato in molti anni di formazione di programmazione di base, di trovarmi in situazioni in cui un allievo tramite questo banale esempio ha capito che:
1. non c’è solo una soluzione ai problemi computazionali
2. la scelta di una soluzione rispetto ad un’altra dipende sempre dal contesto: (esempio: se dobbiamo controllare non un solo numero, ma un insieme di numeri con una cardinalità pari ad un miliardo, quale soluzione finisce prima la uno, la due o la tre ?)
Grazie per l’attenzione.