4 – 5 – 6 Number
Interi
Partiamo subito con degli esempi:
const giorni_settimana = 7; var numeri_festivita_questo_mese = 5;
sia la costante che la variabile sono di tipo number , js utilizza 8 byte , ovvero 8 x 8 = 64 bit per rappresentare qualsiasi numero sia intero che con la virgola.
Esistono librerie che estendono i limiti, tipo quella di Daniel Trabbien.
Vediamo il più grande intero rappresentabile con 64 bit, che è 2 ^ 64 ( ^ vuol dire elevato) – 1 = 18.446.744.073.709.551.615 . Il -1 sta per lo zero e i numeri rappresentabili sarebbero una metà per i numeri positivi e l’altra per i negativi. In js anche il numero intero è rappresentato come un numero decimale con zeri dopo la virgola, quindi una parte di bit viene usate per questi decimali zero. Quelli che avanzano sono 53 bit sono per rappresentare i numeri 2 ^ 53 – 1 = 9.007.199.254.740.991 chiamato max safe integer .
Possiamo verificarlo con
console.log(Number.MAX_SAFE_INTEGER);
Superando il numero massimo intero i calcoli o la valutazione del linguaggio non sono sicure (safe) e rischiano di sbagliare.
Abbiamo una funzione che ci aiuta a restare nel campo safe isSafeInteger
if (Number.isSafeInteger(variabile) ) { usiamo il valore } else { errore }
Reali
Sono i numeri con la virgola o floating point e possono essere memorizzati come interi sia in costanti che in variabili , il separatore tra la parte intera e decimale è il punto .
const pi_greco = 3.14;
possiamo avvalerci anche qui della classe number per il range di rappresentazione con il suo metodo MAX_VALUE
console.log( Number.MAX_VALUE);
Che restituisce il numero massimo reale rappresentabile: 1.7976931348623157e+308 , praticamente possiamo spostare la virgola di 308 posti verso destra.
Vediamo un esempio che fallisce un confronto apparentemente corretto
var x = 0.1 + 0.2; console.log(x); console.log(x == 0.3); console.log(0.1+0.2 == 0.3);
perché il valore che js assegna ad x è 0.30000000000000004 mentre noi possiamo rappresentare un max di 15 cifre decimali.
Ne consegue questa regola: quando abbiamo a che fare con i decimali, mai andare ad eseguire dei confronti di uguaglianza.
Dovremmo calcolare il valore assoluto (senza segno) di una differenza che dovrà essere minore di un delta (quanti numeri decimale) che scegliamo:
console.log(x - 0.3 < 0.00000001);
console.log( Math.abs( x -0.3) < 0.00000001);
Il delta lo posso scegliere secondo le necessità con 4 cifre 0.0001 o con 14 cifre 0.00000000000001. I due esempi portano allo stesso risultato anche se il secondo, che fa uso del metodo abs è concettualmente più corretto.
La classe number oltre al max ha anche il MIN_VALUE che costituisce il numero più vicino allo zero che posso rappresentare
console.log(Number.MIN_VALUE);
che restituisce 5e-324 , cioè 324 posizioni verso con ultimo numero il 5 . Infatti
console.log(Number.MIN_VALUE/2);
js restituirà zero, perche non è in grado di rappresentarlo. Vediamo qual’è il pi grande numero negativo:
console.log(- Number.MAX_VALUE);
che ci da -1.7976931348623157e+308
Ovviamente questi limiti sono davvero estremi da incontrare
Una variabile non inizializzata ha come valore undefined cioè indefinito.
Mentre questo:
var z = 10 - "cucu"; console.log(z);
produce NaN come valore di z cioè Not a Number.
NaN è una costante predefinita di js che significa non è un numero, ma solo a seguito di un ritorno di un’operazione matematica, infatti una stringa per js non equivale a Nan
Possiamo metterci al riparo con una condizione
if (y == undefined) { console.log("Variabile non definita");} else { console.log(z);}
undefined è un valore costante di js. Ovviamente la variabile deve esistere ( almeno var y; ), non esiste una funzione tipo quella di php isset . Per NaN utilizziamo invece una funzione apposita:
if ( isNaN(z)) { console.log("Espressione non computabile");} else { console.log(z);}
Un piccolo cenno bisogna farlo sull’ operatore di confronto, com in php anche in js esiste quello debole e quello forte, infatti
console.log ( 3 = "03");
restituisce come risultato TRUE, perché js trasforma la stringa in numero come
console.log ( 0 = " ");
Sono tutti casi trueffaldini . Bisogna utilizzare l’operatore strict che confronta lo stesso tipo e lo stesso valore e non permette conversioni come il confronto debole:
console.log ( 0 === "00");
Se assegno infatti null alla variabile y di prima
var y = null; if (y == undefined) { console.log("Variabile non definita");}
ottengo true, mentre se uso l’operatore forte === ottengo false.
Con undefined , mi metto al riparo da eventuali errori non previsti (variabile che mi sono dimenticato di definire), mentre con null, decido consapevolmente di non assegnare un valore alla variabile.
In linea generica, specialmente agli inizi, il consiglio è quello di utilizzare sempre l’operatore strict, per non rischiare troppo nei confronti.
Altra chicca:
if ( NaN != Nan) { console.log("Mi arrendo"); }
Per js NaN è diverso da NaN, quindi come regola: non usare mai NaN per espressioni !
undefined e null sono tipi speciali con un solo possibile valore: per l’appunto null e undefined ,rispettivamente.
Vediamo alcuni approfondimenti:
Number.isNaN()
Verifica solo se l’argomento è un NaN. Visto che non possiamo fare NaN == NaN
Gli unici modi per verificare se un valore è NaN è usare o la funzione globale isNaN oppure la funzione isNaN dell’oggetto Number (Number.isNaN).
Se chiami Number.isNaN('dffsdf')
ti dà false perché la stringa non è NaN.
Se metti Number.isNaN('dffsdf'/10)
allora ti ritorna true perché dividere una stringa per un numero ritorna NaN.
La funzione globale isNaN(), Fa la conversione dell’argomento prima di verificare se la conversione darebbe un NaN.
isNaN(”) è false perché la stringa vuota viene convertia a 0. Stessa cosa perisNaN(true), isNaN(false)
perché vengono convertite a 1 e 0 rispettivamente.
Consiglio: Se vuoi verificare un’operazione, usa Number.isNaN :
var res = variabile/altravar
if(Number.isNaN(res))
Puoi usare isNaN per verificare un argomento ma tenendo conto che
”, ‘ ‘, true, false e [] sarebbero “numeri” durante la conversione.
Per effettuare la conversione di una variabile da una stringa a numero, basta utilizzare il segno più (+) davanti al nome della variabile
var num = "10"; num = +num;
si possono usare anche le funzioni predefinite dell’oggetto number parseInt o parseFloat per i decimali
var num = "10"; num = parseInt(num);
Tutte queste casistiche ci sembrano solo teoriche e al limite della pratica o mai riscontrabili, invece non si può mai sapere cosa succede dal lato pratico, cosa un utente può inserire in un campo o come la sfiga può corrompere un file letto da disco o preso da internet… Percui quando la cosa è critica è bene conoscere e tutelarsi.