In questo capitolo si useranno alcune delle nozioni esposte precedentemente ed altre che verranno introdotte per una applicazione un po' più utile di quelle esposte finora, cioè per verificare se un numero scritto dall'utente è primo o no.
Va comunque tenuto presente che la portata di applicazioni aritmetiche di questo tipo è limitata dal fatto che il massimo numero rappresentabile come intero in Javascript è 9007199254740990, quindi per numeri maggiori la procedura fallisce.
Questo è il sorgente.
<!DOCTYPE html> <html lang="it"> <head> <title>Esempio 4</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script> function nPrimo(numero) { // l'argomento è un numero? if (isNaN(numero)) { alert(numero+" non \xe8 un numero."); return; } // se si, è un numero intero? if (parseInt(numero) != numero) { alert(numero+" non \xe8 un numero intero."); return; } // se si, è un naturale maggiore di 1? if (numero<2) { alert("Solo numeri naturali maggiori di 1."); return; } // se il numero è primo l'unico suo divisore proprio è 1 var divisore = 1; // se il numero è 2, è primo e non necessitano controlli if (numero>2) { // il numero è pari? if ((numero & 1)==0) // se si, non è primo divisore = 2; else // altrimenti, se è un dispari < 9, è sicuramente primo /* se è >= 9 si provano tutti i divisori dispari, partendo da 3 fino a che non si supera la radice quadrata del numero*/ if (numero >= 9) for (i=3; i<= Math.sqrt(numero); i+=2) if ((numero % i)==0) { /* se uno di questi divisori dà resto 0, il numero non è primo e si termina il processo */ divisore = i; break; } } //se il divisore è rimasto 1, il numero è primo, altrimenti no if (divisore==1) alert(numero+" \xe8 primo.") else alert(numero+" \xe8 divisibile per " +divisore+".") } </script> </head> <body style="background-color:cyan"> <form name="frm" id="frm" style="position:relative; width:40%; left:30%; top:100px; background-color:azure; color:blue; border-style:solid; border-color:blue; text-align:center"> <h2>controllo di primalità</h2> <p> <label for="campo_n">numero </label> <input type="text" id="campo_n" size="10" value = "2" /> </p> <p> <input type="button" value=" controllo " onclick = "nPrimo(campo_n.value)" /> </p> </form> </body> </html>
L'input viene immesso nel campo campo_n della form frm della pagina HTML. La funzione nPrimo() viene attivata da un click sul bottone nella stessa form. Alla funzione viene passato come argomento il testo contenuto in campo_n. All'interno della funzione l'argomento è indicato dall'identificatore numero.
Nel corpo della funzione, prima di tutto, si controlla che l'input sia adeguato al tipo di elaborazione richiesta.
Se l'argomento non è un numero, la funzione emette un messaggio con alert() ed interrompe l'elaborazione con return.
Per controllare se una stringa di caratteri non può rappresentare un numero si usa la funzione predefinita isNaN() (is not a number).
Se l'argomento, pur essendo un numero, non è intero, lo si rifiuta come sopra.
Per controllare se l'argomento è un intero lo si confronta con con il valore prodotto
dalla funzione predefinita
parseInt()
che cerca, se è possibile, di estrarre
un numero intero da una stringa di caratteri. Se il numero e il valore di
parseInt()
coincidono, il numero è un intero.
Superati tutti i controlli sull'adeguatezza dell'input si può procedere all'analisi aritmetica vera e propria.
Si definisce la variabile divisore cui si assegna il valore iniziale 1. Se tale valore alla fine dell'elaborazione non è mutato, il numero è primo.
Se l'argomento è 2, non si fa nulla. divisore rimane 1 e si va direttamente alla conclusione.
Se il numero è pari, il numero ovviamente non è primo ed divisore
assume valore 2. Per vedere se un numero naturale è pari, il metodo più veloce è
l'operazione bitwise and
, indicata dall'operatore &, con il numero 1.
Si confrontano cioè i bit del numero con quelli corrispondenti di 1, che sono tutti 0 tranne
quello di ordine più basso. Se il numero è pari, tutti i bit del risultato sono 0, altrimenti
il bit di ordine più basso del risultato rimane 1.
Se il numero non è pari ma è < di 9, è 3 o 5 o 7, quindi è primo. Si controllano quindi i numeri da 9 in poi.
Partendo da 3, si provano come divisori tutti i numeri dispari minori della radice quadrata del numero esaminato. Per avere solo i divisori dispari la variabile contatore i viene incrementata ogni volta di due unità (i += 2). Non si effettua la divisione: basta avere il resto e questo si ottiene con l'operatore %.
Se una divisione ha resto zero, il valore della variabile
divisore viene aggiornato e si interrompe il ciclo con
break
.
Se il ciclo for termina senza che ciò succeda, la variabile divisore rimane con valore 1.
Riassumendo e completando:
Un commento può essere inserito nel sorgente di una funzione Javascript in due modi:
|
Una funzione può essere interrotta prima di arrivare all'ultima istruzione con l'istruzione return |
Un ciclo può essere interrotto prima del suo termine regolare con l'istruzione break |
Per controllare se una sequenza di caratteri non può rappresentare un numero si usa la funzione isNaN(stringa). |
Se una stringa rappresenta, anche parzialmente, un valore numerico intero, questo può essere estratto dalla funzione parseInt(stringa). Analogamente, se rappresenta un valore numerico reale, questo può essere estratto dalla funzione parseFloat(stringa) |
Numeri reali (come il pi greco o il numero di Nepero) e funzioni sui numeri reali (come radice, seno, logaritmo...) sono proprietà e metodi dell'oggetto Math, quindi vanno sempre preceduti dal nome dell'oggetto, cui sono uniti da un punto. |
operatore | operazione | esempio |
---|---|---|
+ | addizione | somma = a + b |
* | moltiplicazione | prodotto = a * b |
- | sottrazione | diff = a - b |
/ | divisione | quoz = a / b |
% | modulo (resto tra interi) | resto = a % b |
operatore | operazione | esempio |
---|---|---|
& | and tra bit di interi | c = a & b |
| | or tra bit di interi | c = a | b |
^ | xor tra bit di interi | c = a ^ b |
~ | inversione dei bit di un intero | c = ~a |
>> | shift destro tra bit di interi | c = a >> b |
<< | shift sinistro tra bit di interi | c = a << b |
operatore | esempio | equivalente |
---|---|---|
++ | a++ | a = a + 1 |
-- | a-- | a = a - 1 |
+= | a += b | a = a + b |
-= | a -= b | a = a - b |
*= | a *= b | a = a * b |
/= | a /= b | a = a / b |
%= | a %= b | a = a % b |
&= | a %= b | a = a & b |
|= | a |= b | a = a | b |
^= | a ^= b | a = a ^ b |
>>= | a >>= b | a = a >> b |
<<= | a <<= b | a = a << b |
funzione | effetto | esempio |
---|---|---|
Math.abs(x) | valore assoluto | Math.abs(-2) = 2 |
Math.acos(x) | arcocoseno | Math.acos(1) = 0 |
Math.asin(x) | arcoseno | Math.asin(1) = Math.PI/2 |
Math.atan(x) | arcotangente | Math.atan(1) = Math.PI/4 |
Math.atan2(y,x) | coefficiente angolare della la retta passante per l'origine e il punto P(x,y) | Math.atan2(1,1) = 1 |
Math.ceil(x) | il numero intero immediatamente maggiore | Math.ceil(Math.PI) = 4 |
Math.cos(x) | coseno | Math.cos(Math.PI) = -1 |
Math.exp(x) | esponenziale | Math.exp(1) = Math.E |
Math.cos(x) | coseno | Math.cos(Math.PI) = -1 |
Math.floor(x) | il numero intero immediatamente minore | Math.floor(Math.PI) = 3 |
Math.log(x) | logaritmo naturale | Math.log(Math.E) = 1 |
Math.max(x,y) | il maggiore dei due numeri | Math.max(3,4) = 4 |
Math.min(x,y) | il minore dei due numeri | Math.min(3,4) = 3 |
Math.pow(x,y) | elevamento a potenza | Math.pow(3,4) = 81 |
Math.random() | genera un numero reale a caso compreso tra 0 e 1 | Math.floor(Math.random()) = 0 |
Math.round(x) | arrotonda x all'intero più vicino | Math.round(Math.PI) = 3 |
Math.sin(x) | seno | Math.sin(Math.PI/2) = 1 |
Math.sqrt(x) | radice quadrata di x | Math.sqrt(81) = 9 |
Math.tan() | tangente | Math.tan(Math.PI/4) = 1 |
costante | descrizione | valore approssimato |
---|---|---|
Math.E | base dei logaritmi naturali:numero di Nepero | 2.718281828459045235... |
Math.LN2 | logaritmo naturale di 2 | 0.693147180559945309... |
Math.LN10 | logaritmo naturale di 10 | 2.302585092994045684... |
Math.LOG2E | logaritmo in base 2 di E | 1.442695040888963407... |
Math.LOG10E | logaritmo in base 10 di E | 0.434294481903251827... |
Math.PI | pi greca | 3.141592653589793238... |
Math.SQRT2 | radice quadrata di 2 | 1.414213562373095049... |
Math.SQRT1_2 | radice quadrata di 1/2 | 0.707106781186547524... |