Cerca

modulo attività

modulo tecnica

Login Form

Il computer non è in grado di trattare i numeri reali ma solo una loro approssimazione.

Lo fa ognuno di noi quando deve usare il "pi.greco", mica pensiamo di usare molto più di 5 o 6 cifre decimali? 

Il numero delle cifre decimali di "pi.greco" è infinito e questo significa che se lo si volesse usare completo non si avrebbe né abbastanza carta, né abbastanza memporioa, né abbastanza tempo per eseguire i calcoli per cui lo dobbiamo comunque approssimare alla lunghezza che ci fa comodo o che sia significativo per il risultato che aspettiamo.

Il computer deve, perlomeno, fare lo stesso visto che ha una memoria di dimensioni limitate da assegnare a ciascun numero.

In aggiunta il computer fa altre approssimazioni in quanto al suo interno usa numeri in base 2 e non in base dieci.

La formalizzazione di tutti problemi connessi con la rappresentazione di numeri in un computer è fissata nello standard "IEEE 754".

numMacch2L'applicazione di Scratch "numeri macchina" è stata creata per sondare almeno in parte questi limiti.

Alla sua apertura con "bandierina verde" sono disponibili numerosi tasti per creare rapidamente numeri molto grandi o molto piccoli a partire dal numero "1", fissato per default.

L'atteggiamento più produttivo è provare con numeri diversi e osservare cosa accade modificando il valore di X a piacere.

Con i pulsanti arancione si eseguono moltiplicazioni successive del valore iniziale di X per il fattore indicato sul pulsante e con i pulsanti verdi si eseguono divisioni successive per il divisore indicato sul pulsante. 

Per esempio, già moltiplicando per 1e-30, cioè dividendo per 1030, si vede che il numero "1" è diventato 9,999999999999999e-31: significa che nella memoria del computer c'è una solo un'approssimazione del numero (nota 1) Il visore ci fa vedere ancora "1" solo perchè il programmatore del visore ha voluto così.

Se, invece, si divide per 10 un po' di volte, si vede che già alla sesta iterazione sono state aggiunte altre cifre sigificative per cui il numero non è più identico all'originale, cioé risulta corrotto.

La corruzione del numero sembra minima ma se si esegue unl test con l'istruzione "se (x=1), allora... altrimenti..." si vede che il risultato del test è "falso" in quanto il valore di X, quello contenuto nella memoria del PC, è vicinissimo ad 1 da cui differisce solo alla 16^ cifra significativa ma non è esattamente "1".numMacch1

Premere [tasto 1] per verificare.

In questo test il numero 1 viene diviso 8 volte per 10 e poi moltiplicato altrettante volte per 10: dovremmo avere lo stesso numero ed infatti sul visore si vede ancora il numero "1" ma le cose non stanno propriamente in questo modo: per un computer può accadere che il valore di x posto uguale a 1 sul visore non sia uguale a "1".

... in che senso?

Il computer confronta un numero esatto, intero, il numero "1", con il valore di "x" contenuto in una memoria del computer.

Se questo valore è stato oggetto di operazioni numeriche successive il risultato dopo ciascun calcolo viene approssimato alla cifra binaria più vicina che il computer è in grado di assegnargli.

Il risultato è che qualche cifra decimale, trascurabilissima per la sua insignificanza pratica, sia leggermente diversa da quanto ci si aspetterebbe da un computer "serio".

Il fatto è che il computer è "serissimo" solo che non può fare più di quanto i suoi limiti di memoria e le base dei suoi calcoli possano permettergli di fare.

Il computer è stato costruito per manipolare numeri binari di lunghezza limitata che necessitano di approssimazioni per la sua memorizzazione.

 

Prove sulla visualizzazikone dei numeri

Con [tasto X]:

- inserire una stringa di testo, per esempio, "abc", moltiplicare per "1" e si vede che il valore è"0";

- inserire "0.0000005" (ATTENZIONE! usare il punto decimale e non la virgola) e si vede l'intera cifra (nota 2); se si moltiplica poi per 1 si vede "0" solo perché il visore non mostra più di 6 cifre decimali. Se si moltiplica per mille si rivede il valore corretto della cifra inserita, ma, guarda caso, solo in modo approssimato "4,999999999999999e-10" (nota 1);

- con un qualunque valore andare a vedere cosa accade quando l'esponente approssima 308 o -308 così si rileva che si vanno perdendo cifre significative fino a smarrire del tutto ogni parentela col numero iniziale. Il computer è andato in overflow o in underflow;

- se si parte dal numero "1" e lo si divide per 10 molte volte si vede che solo a partire da un esponente pari a -312 le cifre significative cominciano a "deteriorarsi" progressivamente a cominciare da quella più a destra. Il numero perde di significato solo dopo 9,88*10-324 dove solo il "9" ha senso mentre le altre cifre arrivano da chissà dove. (nota 3);

- se si parte dal numero "1" e lo si moltiplica molte volte per 10 si vede che oltre 1*10308 diventa "infinity", come stabilito dalle norme IEEE 754;

- inserire un numero di venti cifre intere "12345678901234567890" (nota 2) e moltiplicare per "1". Risultato : "1234568790123456800". Si vede che le due cifre più a destra sono già scomparse e sostituite con uno "0" e la terzultima è stata approssimata alla più vicina passando da "7" a "8". Scratch ha correttamente scritto 16 cifre significative ed ha arrotondato la meno significativa (nota 1)

- inserire un numero di 30 cifre intere (nota 2), moltiplicare per "1". Risultato: "1,23456789012345e-29; si vede che ci sono 16 cifre significative (nota 1). Dividere per 1030 e vedere che le cifre significative sono 17

 

Altre prove

[tasto 2]: test per verificare che ripetere per 10 volte la somma x:= x+0,1 a partire da x=0 non da' "1";

[tasto 3]: test per verificare che ripetere per 8 volte la somma x:= x+0,125 a partire da x=0 da' "1"

[tasto 4]: test per verificare che ripetere per 64 volte la somma x:= x+0,015625 a partire da x=0 da' "1" 

Perchè questa disparità di trattamento?

0,125 e 0,015625 sono numeri decimali memorizzati esattamente in macchina perchè sottomultipli di 2,

0,1 è un numero decimale non sottomultiplo di 2 per cui viene approssimato dalla macchina con la numerazione binaria "al meglio" ma non esattamente uguale e il test da' "falso" come risultato.

Questa approssimazione è "fatale" nei test di uguagliuanza ma nei calcoli tecnici e scientifici non costituisce un problema.

Inserire nel programma di Scratch condizioni del tipo "se un (valore) è uguale ad un numero" e non si è sicuri che tali valori possano essere identici nella memoria in tutte le sue cifre, anche quelle non visibili (per tutte si intende sia l'esopnente che la parte significativa) ci si potrebbe trovare in una situazione di errore computazionale con conseguenze sullo sviluppo successivo del programma.

 

Ecco alcuni articoli che sviluppano approfonditamente il problema:

"Aritmetica di macchina e analisi dell'errore" (uniba) di Cinzia Elia e Felice Iavernaro,

"Numeri di macchina" (diapositive) di Luca Zanni e Marco Prato,

"Rappresentazione di numeri in macchina. Condizionamento e stabilità" (polito) di Stefano Berrone.

"Rappresentazioni" in virgola mobile uniroma2 Valeria Cardellini.

 

note

nota 1: sono 16 cifre significative.

nota 2: ogni valore inserito viene trattato inizialmente come una stringa, solo dopo un'operazione Scratch "capisce" se deve trattarlo come un numero o come una stringa. È stata inserita una procedura di controllo della virgola decimale ma è bene prendere l'abitudine di utilizzare il punto decimale.

nota 3: il numero, scritto diversamente, è: 0,988*10-323. Sembra sia possibile scendere a numeri con esponente minore di -308 come previsto dalo standard IEEE 754. Ma se c'erano 16 cifre a disposizione per la mantissa e ne sono state corrotte 15 si è dovuti passare da esponente -308 ad esponente -308-15= -323 prima di vedere scomparire l'ultima cifra superstite del numero originale. Notare che subito dopo anche Scratch si "rifiuta" di continuare a dividere per 10 ponendo il valore a 0 anche se "appaiono" delle cifre non nulle ma che sappiamo casuali.