RAPPRESENTAZIONE DELL’INFORMAZIONE

Slides:



Advertisements
Presentazioni simili
Dall’informazione al linguaggio macchina
Advertisements

Rappresentazioni numeriche
Informatica Generale Susanna Pelagatti
Rappresentazione di Numeri Reali
Rappresentazioni numeriche
Sistemi di numerazione
Le Informazioni e la loro Rappresentazione nei calcolatori
Trasmissione delle informazioni
Codifica dei Dati Idea: vogliamo rappresentare dati eterogenei utilizzando un linguaggio che l’elaboratore puo’ facilmente manipolare Essenzialmente vogliamo.
Sistemi di numerazione e codici
Fondamenti di Informatica CDL in Ingegneria Meccanica - A.A CDL in Ingegneria Meccanica - A.A Tipi di dati Ing. Simona Colucci.
Fondamenti di Informatica CDL in Ingegneria Gestionale - A.A Tipi di dati Ing. Simona Colucci.
1 © 1999 Roberto Bisiani Rappresentazione delle informazioni n Occorre un codice n Legato alla tecnologia usata Robustezza Semplicita Economicita.
Strategie per la progettazione di algoritmi:
Rappresentazione dei dati e codifica delle informazioni
1 Sistemi Digitali. 2 Definizione Analog Waveform Time Voltage (V) 0 5 Digital Waveform Time Voltage (V)
Sistemi Digitali.
Informatica 3 Codifica binaria.
Corso di Informatica (Programmazione)
1 Corso di Laurea in Biotecnologie Informatica (Programmazione) Rappresentazione dellinformazione su calcolatore Anno Accademico 2009/2010.
Corso di Informatica (Programmazione)
Esistono 10 tipi di persone al mondo: Quelli che conoscono il codice binario & Quelli che non lo conoscono.
Rappresentazioni numeriche
1 Sistemi Digitali. 2 Definizione Analog Waveform Time Voltage (V) 0 5 Digital Waveform Time Voltage (V)
Rappresentazioni numeriche. Introduzione Un calcolatore elettronico dispone di uno spazio finito per memorizzare le cifre che esprimono un valore numerico.
I numeri by iprof.
Algebra di Boole L’algebra di Boole è un formalismo che opera su variabili (dette variabili booleane o variabili logiche o asserzioni) che possono assumere.
Gli esseri viventi ricevono informazione direttamente dal mondo circostante e dai propri simili attraverso i sensi (percezione). La percezione, tuttavia,
Codifica binaria Rappresentazione di numeri
Il Linguaggio C.
Programma del corso Dati e loro rappresentazione Architettura di un calcolatore Sistemi operativi Linguaggi di programmazione Applicativi: - fogli elettronici.
Usare rappresentazioni di lunghezza fissa porta ad avere valori non rappresentabili: Overflow indica un errore nella rappresentazione del risultato in.
Conversione binario - ottale/esadecimale
Conversione binario - ottale/esadecimale
Algoritmi e Programmazione (in C) Stefano Cagnoni e Monica Mordonini
Rappresentazione di Numeri Reali
INSIEMI NUMERABILI L’analisi matematica introduce il concetto di insieme numerabile come insieme i cui elementi possono essere “contati” ossia che possiede.
LINGUAGGI DI PROGRAMMAZIONE
Rappresentazione dell’informazione
RAPPRESENTAZIONE DELL'INFORMAZIONE
Dalle potenze ai numeri binari
Che cos’è un sistema di numerazione?
1 Numeri interi e numeri in virgola mobile F. Bombi 2 6 novembre 2003.
Rappresentazione dell’informazione nel calcolatore.
Rappresentazione Dati Codificare informazioni nel Computer
ARCHITETTURA DEI SISTEMI ELETTRONICI
La nuova Teoria della moltiplicazione, somma e sottrazione di Cristiano Armellini
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Codifica binaria dell’informazione Marco D. Santambrogio – Ver. aggiornata al 11.
Rappresentazione della Informazione
Rappresentazioni numeriche. Introduzione Un calcolatore elettronico dispone di uno spazio finito per memorizzare le cifre che esprimono un valore numerico.
Rappresentazione dell’informazione
Rappresentazioni a lunghezza fissa: problemi
Fondamenti di Informatica
La Rappresentazione dell’Informazione
Rappresentazione dell'informazione
L’ELABORATORE ELETTRONICO uno strumento in grado di eseguire insiemi di azioni (“mosse”) elementari le azioni vengono eseguite su oggetti (dati) per produrre.
Rappresentazione dell'informazione 1 Se ho una rappresentazione in virgola fissa (es. su segno e 8 cifre con 3 cifre alla destra della virgola) rappresento.
La codifica dei numeri.
Conversione binario-ottale/esadecimale
Rappresentazione degli interi
Informatica Lezione 3 Psicologia dello sviluppo e dell'educazione (laurea magistrale) Anno accademico:
Codifica dei numeri Il codice ASCII consente di codificare le cifre decimali da “0” a “9” fornendo in questo modo una rappresentazione dei numeri Per esempio:
Codifica binaria dell’informazione
Rappresentazione dei numeri
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Codifica binaria dell’informazione Marco D. Santambrogio – Ver. aggiornata al 24.
I sistemi di numerazione
La numerazione ottale. Il sistema di numerazione ottale ha ampio utilizzo in informatica E’ un sistema di numerazione posizionale La base è 8 Il sistema.
© 2015 Giorgio Porcu - Aggiornamennto 09/12/2015 I STITUTO T ECNICO SECONDO BIENNIO T ECNOLOGIE E P ROGETTAZIONE Rappresentazione dell’ Informazione Conversioni.
Rappresentazione delle informazioni negli elaboratori L’entità minima di informazione all’interno di un elaboratore prende il nome di bit (binary digit.
Transcript della presentazione:

RAPPRESENTAZIONE DELL’INFORMAZIONE Internamente a un elaboratore, ogni informazione è rappresentata tramite sequenze di bit (cifre binarie) Una sequenza di bit non dice “cosa” essa rappresenta: l’interpretazione è negli occhi di chi guarda Ad esempio, 01000001 può rappresentare: l’intero 65, il carattere ‘A’, il boolean ‘vero’, … … il valore di un segnale musicale, … il colore di un puntino sullo schermo...

INFORMAZIONI NUMERICHE La rappresentazione delle informazioni numeriche è di particolare rilevanza In particolare vogliamo poter trattare: numeri naturali (interi senza segno) numeri interi (con segno) numeri reali con la consapevolezza di: eventuali limiti nella loro rappresentazione e nel loro uso eventuali approssimazioni necessarie.

NUMERI NATURALI (interi senza segno) Dominio: N = { 0,1,2,3, …} Rappresentabili con diverse notazioni non posizionali ad esempio la notazione romana: I, II, III, IV, V, .... IX, X, XI... posizionale 1, 2, .. 10, 11, ... 200, ...

NUMERI NATURALI (interi senza segno) Non posizionali: hanno regole proprie, che rendono spesso assai complessa l'esecuzione dei calcoli Dominio: N = { 0,1,2,3, …} Rappresentabili con diverse notazioni non posizionali ad esempio la notazione romana: I, II, III, IV, V, .... IX, X, XI... posizionale 1, 2, .. 10, 11, ... 200, ... Posizionale: rappresenta i numeri in modo compatto, e rende semplice l'ef- fettuazione dei calcoli

NOTAZIONE POSIZIONALE Concetto di base di rappresentazione B Rappresentazione del numero come sequenza di simboli (cifre) appartenenti a un alfabeto di B simboli distinti ogni simbolo rappresenta un valore compreso fra 0 e B-1 Esempio (base B = tre, alfabeto A = {$,%,#}): $ rappresenta il valore zero % rappresenta il valore uno # rappresenta il valore due

NOTAZIONE POSIZIONALE Il valore di un numero espresso in questa notazione è ricavabile a partire dal valore rappresentato da ogni simbolo pesandolo in base alla posizione che occupa nella sequenza dn-1 … d2 d1 d0 Posizione n-1: pesa Bn-1 Posizione 1: pesa B1 Posizione 0: pesa B0 (unità)

NOTAZIONE POSIZIONALE Il valore di un numero espresso in questa notazione è ricavabile a partire dal valore rappresentato da ogni simbolo pesandolo in base alla posizione che occupa nella sequenza Esempio ($ indica zero, % indica uno, # indica due): %## rappresenta il valore diciassette %$% rappresenta il valore dieci

NOTAZIONE POSIZIONALE Il valore v di un numero espresso in questa notazione è ricavabile a partire dal valore rappresentato da ogni simbolo pesandolo in base alla posizione che occupa nella sequenza In formula: B = base, dk = cifre (ognuna rappresenta un valore fra 0 e B-1)

NOTAZIONE POSIZIONALE Quindi, una sequenza di cifre (stringa) non è interpretabile se non si precisa la base in cui è espressa Esempi:

NOTAZIONE POSIZIONALE Ogni numero può essere espresso, in modo univoco, in una qualunque base Esempi:

CONVERSIONI stringa/numero/stringa Ogni numero può essere espresso, in modo univoco, in una qualunque base Quindi, deve essere possibile: data la rappresentazione di un numero in una certa base, determinare il valore del numero dato un numero, determinare la sua rappresentazione in una certa base

CONVERSIONI stringa/numero/stringa Ogni numero può essere espresso, in modo univoco, in una qualunque base Quindi, deve essere possibile: data la rappresentazione di un numero in una certa base, determinare il valore del numero dato un numero, determinare la sua rappresentazione in una certa base Conversione da stringa a numero Conversione da numero a stringa

CONVERSIONE STRINGA / NUMERO Problema: data la rappresentazione di un numero in una certa base, determinare il valore del numero Soluzione: applicare la formula

CONVERSIONE NUMERO / STRINGA Problema: dato un numero, determinare la sua rappresentazione Soluzione: dipende se la rappresenta-zione scelta è posizionale o meno se non è posizionale, le regole dipendono dalla specifica rappresentazione ad esempio, ventisette in notazione romana: 27 è compreso fra 20 e 30  accumulo 20  XX 27-20 = 7 è compreso fra 5 e 10  accumulo 5  V 7-5 = 2 si esprime direttamente  II morale: XXVII

CONVERSIONE NUMERO / STRINGA Problema: dato un numero, determinare la sua rappresentazione in una base data Soluzione (notazione posizionale): manipolare la formula per dedurre un algoritmo v è noto, le cifre dk vanno calcolate

CONVERSIONE NUMERO / STRINGA d0 si può ricavare come resto della divisione intera v / B tale divisione ha per quoziente q = d1 + B * ( d2 + B * ( d3 + ... )), che consente di trovare le altre cifre iterando il procedimento NB: le cifre vengono prodotte nell'ordine dalla meno signifi- cativa (LSB) alla più significativa (MSB)

CONVERSIONE NUMERO / STRINGA Algoritmo delle divisioni successive d0 si può ricavare come resto della divisione intera v / B tale divisione ha per quoziente q = d1 + B * ( d2 + B * ( d3 + ... )), che consente di trovare le altre cifre iterando il procedimento NB: le cifre vengono prodotte nell'ordine dalla meno signifi- cativa (LSB) alla più significativa (MSB)

CONVERSIONE NUMERO / STRINGA Algoritmo delle divisioni successive si divide v per B il resto costituisce la cifra meno significativa il quoziente serve a iterare il procedimento se tale quoziente è zero, l’algoritmo termina; se non lo è, lo si assume come nuovo valore v’, e si itera il procedimento con il valore v’.

CONVERSIONE NUMERO / STRINGA Esempi

RAPPRESENTAZIONI IN BASI DIVERSE In generale, le rappresentazioni di uno stesso numero in basi diverse non sono correlate fra loro Esempio: il numero sessantasette B1 = 2  “01000011” B2 = 8  “103” B3 = 10  “67” B4 = 16  “43”

RAPPRESENTAZIONI IN BASI DIVERSE Tuttavia, diventano correlate se le basi considerate sono una potenza una dell’altra: B2 = (B1 )N Allora, N cifre nella rappresentazione in base B1 corrispondono esattamente a 1 cifra nella rappresentazione in base B2

RAPPRESENTAZIONI IN BASI DIVERSE Tuttavia, diventano correlate se le basi considerate sono una potenza una dell’altra Esempio: B1 = 2  “01000011” B2 = 8 = 23 = (B1)3  “103” 01.000.011 B3 = 10  “67” B4 = 16 = 24 = (B1)4  “43” 0100.0011 8 = 23 1 cifra ottale = 3 cifre binarie 16 = 24 1 cifra hex = 4 cifre binarie

RAPPRESENTAZIONI IN BASI DIVERSE Conseguenza: se le basi considerate sono una potenza una dell’altra, per passare dalla rappresentazione di un numero in una base B1 alla sua rappre-sentazione in un’altra base B2 = (B1 )N basta sostituire ordinatamente N cifre della rappresentazione B1 con 1 cifra della rappresentazione B2

RAPPRESENTAZIONI IN BASI DIVERSE

OPERAZIONI IN NOTAZIONE POSIZIONALE Tutte le notazioni posizionali usano le stesse regole per le operazioni, indipen-dentemente dalla base adottata Esempi di somme e sottrazioni:

OPERAZIONI IN NOTAZIONE POSIZIONALE In moltiplicazioni e divisioni: spostando tutte le cifre a sinistra di una posizione (e introducendo uno 0 a destra) si moltiplica per la base spostando tutte le cifre a destra di una posizione (e introducendo uno 0 a sinistra) si divide per la base Esempi: base dieci: 184 * 10 = 1840 base dieci: 1832 / 10 = 183 _ base due: 1011 * 2 = 10110 base due: 1111 / 2 = 111 _ Divisione intera

OPERAZIONI IN NOTAZIONE POSIZIONALE Due mosse elementari: Shift Left (SHL) Shift Right (SHR) Qualunque moltiplicazione o divisione può essere espressa con somme, sottrazioni e SHL / SHR.

ERRORI NELLE OPERAZIONI In matematica, le operazioni sui naturali non danno mai luogo a errori (posto che la divisione è una divisione intera, che può comportare l’esistenza di un resto) In un elaboratore, invece, si possono generare errori, a causa dell’impossibilità di rappresentare tutti gli infiniti numeri in particolare, con N bit il massimo numero rappresentabile è 2N-1 qualunque operazione che implichi un risultato maggiore sarà errata  OVERFLOW

ERRORI NELLE OPERAZIONI Teoricamente Praticamente il risultato è completamente errato, perché è andato perso proprio il contributo più significativo (MSB) Soluzione: usare un tipo di dato che offra un maggior numero di bit

IMPLEMENTARE GLI ALGORITMI Conversione da stringa a numero si applica la formula richiede la valutazione di un polinomio  Metodo di Horner le cifre dk sono note, il valore v va calcolato

IMPLEMENTARE GLI ALGORITMI Conversione da stringa a numero una funzione: sToNum() in ingresso: base b stringa di simboli, s lunghezza della stringa, len in uscita: il valore del numero (intero senza segno)

IMPLEMENTARE GLI ALGORITMI unsigned long sToNum( unsigned short b, char s[], int len) { <finché ci sono simboli in s> <calcola il valore del simbolo s[i]> <aggiorna il valore v> <alla fine, v rappresenta il valore cercato> }

IMPLEMENTARE GLI ALGORITMI unsigned long sToNum( unsigned short b, char s[], int len) { unsigned long v = 0; <finché ci sono simboli in s> <calcola il valore del simbolo s[i]> <aggiorna il valore v> <alla fine, v rappresenta il valore cercato> }

IMPLEMENTARE GLI ALGORITMI unsigned long sToNum( unsigned short b, char s[], int len) { unsigned long v = 0; int i = 0; for(i=0; i<len; i++) { <calcola il valore del simbolo s[i]> <aggiorna il valore v> } <alla fine, v rappresenta il valore cercato>

IMPLEMENTARE GLI ALGORITMI unsigned long sToNum( unsigned short b, char s[], int len) { unsigned long v = 0; int i = 0; for(i=0; i<len; i++) { val = valoreCifra(s[i]); v = b * v + val; /* Horner */ } <alla fine, v rappresenta il valore cercato>

IMPLEMENTARE GLI ALGORITMI unsigned long sToNum( unsigned short b, char s[], int len) { unsigned long v = 0; int i = 0; for(i=0; i<len; i++) { v = b * v + valoreCifra(s[i]);; } return v; valoreCifra(), chi era costei ?

IMPLEMENTARE GLI ALGORITMI unsigned valoreCifra(char ch) { come fare per calcolare il valore? } il carattere è rappresentato internamente da un numero, secondo la codifica ASCII è garantito che i caratteri da ‘0’ a ‘9’ sono in sequenza: quindi, se ‘0’ è rappresentato internamente dal numero  ‘1’ deve essere rappresentato dal numero  +1, ‘2’ deve essere rappresentato dal numero  +2, … ‘9’ deve essere rappresentato dal numero  +9

IMPLEMENTARE GLI ALGORITMI unsigned valoreCifra(char ch) { come fare per calcolare il valore? } conseguenza: la differenza tra un carattere numerico (compreso fra ‘0’ e ‘9’) e il carattere ‘0’ è proprio il valore del simbolo stesso! ‘0’ -’0’ =  -  = 0 ‘1’ -’0’ = (+1) -  = 1 ‘2’ -’0’ = (+2) -  = 2 … ‘9’ -’0’ = (+9) -  = 9

IMPLEMENTARE GLI ALGORITMI unsigned valoreCifra(char ch) { come fare per calcolare il valore? } lo stesso approccio vale per le lettere da ‘A’ a ‘F’ che rappresentano i valori da 10 a 15 nel caso della base sedici (esadecimale); quindi, se ‘A’ è rappresentato internamente dal numero  ‘B’ deve essere rappresentato dal numero  +1, ‘C’ deve essere rappresentato dal numero  +2, … ‘Z’ deve essere rappresentato dal numero  +25

IMPLEMENTARE GLI ALGORITMI unsigned valoreCifra(char ch) { come fare per calcolare il valore? } e anche per le minuscole da ‘a’ a ‘f’, che pure rappresentano i valori da 10 a 15: se ‘a’ è rappresentato internamente dal numero  ‘b’ deve essere rappresentato dal numero  +1, ‘c’ deve essere rappresentato dal numero  +2, … ‘z’ deve essere rappresentato dal numero  +25

IMPLEMENTARE GLI ALGORITMI unsigned valoreCifra(char ch) { come fare per calcolare il valore? } conseguenza: la differenza tra un carattere alfabetico compreso fra ‘A’ e ‘F’ (o fra ‘a’ e ‘f’) e il carattere ‘A’ (oppure, rispettivamente, ‘a’) consente di trovare il valore corrispondente ‘A’ -’A’ =  -  = 0  sommando 10 ottengo 10 ‘B’ -’A’ = ( +1) -  = 1  sommando 10 ottengo 11 ‘C’ -’A’ = ( +2) -  = 2  sommando 10 ottengo 12 … ‘F’ -’A’ = ( +5) -  = 5  sommando 10 ottengo 15

IMPLEMENTARE GLI ALGORITMI unsigned valoreCifra(char ch) { return ('0'<= ch)&&(ch <= '9') ? ch - '0' : ('a'<= ch)&&(ch <= 'f') ? ch - 'a' + 10 : ('A'<= ch)&&(ch <= 'F') ? ch - 'A' + 10 : BOH; } Qui la funzione è indeterminata (questo caso non dovrebbe mai verificarsi)

IMPLEMENTARE GLI ALGORITMI un approccio ricorsivo unsigned long sToNum( unsigned short b, char s[], int len) { <se len=0, il valore è 0> <se len=1, il valore è val(s[0])> <in ogni altro caso, il valore è val(s[len-1]) + b * sToNum(b,s,len-1) > }

IMPLEMENTARE GLI ALGORITMI un approccio ricorsivo unsigned long sToNum( unsigned short b, char s[], int len) { if (len==0) return 0; else if (len==1) return valoreCifra(s[0]); else return valoreCifra(s[len-1]) + b * sToNum(b,s,len-1) ; }

IMPLEMENTARE GLI ALGORITMI Esempio: un cliente main(){ char st[] = "367"; unsigned long val8 = sToNum(8, st,3); unsigned long val10 = sToNum(10,st,3); unsigned long val16 = sToNum(16,st,3); /* quanto valgono le variabili? */ } Provare con entrambe le versioni di sToNum()

CONVERSIONE NUMERO / STRINGA Problema: dato un numero, determinare la sua rappresentazione in una base data Soluzione (notazione posizionale): manipolare la formula per dedurre un algoritmo v è noto, le cifre dk vanno calcolate

IMPLEMENTARE GLI ALGORITMI Algoritmo delle divisioni successive si divide v per B il resto costituisce la cifra meno significativa il quoziente serve a iterare il procedimento se tale quoziente è zero, l’algoritmo termina; se non lo è, lo si assume come nuovo valore v’, e si itera il procedimento con il valore v’.

IMPLEMENTARE GLI ALGORITMI Conversione da numero a stringa una funzione: numToS() in ingresso: base b numero n in uscita: stringa di simboli, s (lunghezza della stringa) la passiamo come parametro (passa per riferimento) ipotesi: inizialmente è vuota ed è sufficientemente lunga implicita nella stringa

IMPLEMENTARE GLI ALGORITMI void numToS(unsigned short b, unsigned long v, char s[]) { <ripeti> <calcola il resto v%B> <calcola il carattere corrispondente e inseriscilo in testa alla stringa> <sostituisci a v il nuovo valore v/B > <per tutto il tempo che v>0 > }

IMPLEMENTARE GLI ALGORITMI void numToS(unsigned short b, unsigned long v, char s[]) { <ripeti> <calcola il resto v%B> <calcola il carattere corrispondente> <inseriscilo in testa alla stringa> <sostituisci a v il nuovo valore v/B > <per tutto il tempo che v>0 > } occorre scrivere una funzione char convertiCifra(unsigned int) occorre scrivere una procedura void aggiungiInTesta(...) che lo faccia

IMPLEMENTARE GLI ALGORITMI void numToS(unsigned short b, unsigned long v, char s[]) { do { <calcola il resto v%B> <calcola il carattere corrispondente e inseriscilo in testa alla stringa> <sostituisci a v il nuovo valore v/B > } while (v>0); }

IMPLEMENTARE GLI ALGORITMI void numToS(unsigned short b, unsigned long v, char s[]) { do { resto = v % b; <calcola il carattere corrispondente e inseriscilo in testa alla stringa> <sostituisci a v il nuovo valore v/B > } while (v>0); }

IMPLEMENTARE GLI ALGORITMI void numToS(unsigned short b, unsigned long v, char s[]) { do { resto = v % b; ch = convertiCifra(resto); aggiungiInTesta(ch,s); <sostituisci a v il nuovo valore v/B > } while (v>0); }

IMPLEMENTARE GLI ALGORITMI void numToS(unsigned short b, unsigned long v, char s[]) { do { resto = v % b; ch = convertiCifra(resto); aggiungiInTesta(ch,s); v = v / b; } while (v>0); }

IMPLEMENTARE GLI ALGORITMI void numToS(unsigned short b, unsigned long v, char s[]) { do { ch = convertiCifra(v % b); aggiungiInTesta(ch,s); v = v / b; } while (v>0); }

IMPLEMENTARE GLI ALGORITMI void numToS(unsigned short b, unsigned long v, char s[]) { do { aggiungiInTesta( convertiCifra(v % b), s); v = v / b; } while (v>0); }

IMPLEMENTARE GLI ALGORITMI char convertiCifra(unsigned n) { return ( 0 <= n)&&(n <= 9) ? n + '0' : (10 <= n)&&(n <= 15) ? n - 10 + 'A' : '_'; } Qui la funzione è indeterminata (questo caso non dovrebbe mai verificarsi)

IMPLEMENTARE GLI ALGORITMI void aggiungiInTesta( char ch, char st[]) { <sposta tutti i caratteri a destra di una posizione, per fare posto al nuovo carattere> <copia il nuovo carattere nella prima posi- zione della stringa> }

IMPLEMENTARE GLI ALGORITMI void aggiungiInTesta( char ch, char st[]) { int i; for(i=strlen(st); i>=0; i--){ st[i+1] = st[i]; } <copia il nuovo carattere nella prima posi- zione della stringa> }

IMPLEMENTARE GLI ALGORITMI void aggiungiInTesta( char ch, char st[]) { int i; for(i=strlen(st); i>=0; i--) st[i+1] = st[i]; st[0] = ch; }

IMPLEMENTARE GLI ALGORITMI Esempio: un cliente main(){ char s2[10] = "", s8[5] = "", s10[5] = "", s16[5] = ""; numToS( 2, 250, s2); numToS( 8, 250, s8); numToS(10, 250, s10); numToS(16, 250, s16); /* quanto valgono le stringhe? */ }

IMPLEMENTARE GLI ALGORITMI un approccio ricorsivo void numToS(unsigned short b, unsigned long v, char s[]) { <calcola il carattere corrispondente al resto v%B e inseriscilo in coda alla stringa> <se v=0, ritorna> [altrimenti] <calcola la stringa corrisp. a v/B> } È la ricorsione che “inverte l’ordine”

NUMERI INTERI (con segno) Dominio: Z = { …, -2,-1,0,1,2,3, … } Rappresentare gli interi in un elabora- tore pone alcune problematiche: come rappresentare il “segno meno”? possibilmente, rendere semplice l’esecuzione delle operazioni magari usando gli stessi circuiti usati per i naturali…?

NUMERI INTERI (con segno) Due possibilità: rappresentazione in modulo e segno semplice e intuitiva… … ma inefficiente e complessa nella gestione delle operazioni  non molto usata in pratica rappresentazione in complemento a due meno intuitiva, costruita “ad hoc” ma efficiente e capace di rendere semplice la gestione delle operazioni  largamente usata

NUMERI INTERI (con segno) Rappresentazione in modulo e segno un bit per rappresentare il segno 0 = + 1 = - N-1 bit per rappresentare il valore assoluto Esempi (su 8 bit, MSB rappresenta il segno): + 5 = 0 0000101 - 36 = 1 0100100

NUMERI INTERI (con segno) Rappresentazione in modulo e segno Difetti: due diverse rappresentazioni per lo zero + 0 = 00000000 - 0 = 10000000 occorrono algoritmi speciali per fare le operazioni se si adottano le usuali regole, non è verificata la proprietà X + (-X) = 0 occorrono regole (e quindi circuiti) ad hoc

NUMERI INTERI (con segno) +5 0 0000101 -5 1 0000101 --- ---------- 0 1 0001010 Cos’è questa roba??? (+5) + (-5) = -10 ??? Rappresentazione in modulo e segno Difetti: due diverse rappresentazioni per lo zero + 0 = 00000000 - 0 = 10000000 occorrono algoritmi speciali per fare le operazioni se si adottano le usuali regole, non è verificata la proprietà X + (-X) = 0 occorrono regole (e quindi circuiti) ad hoc

NUMERI INTERI (con segno) Rappresentazione in complemento a due si vogliono poter usare le regole standard per fare le operazioni in particolare, si vuole che X + (-X) = 0 la rappresentazione dello zero sia unica anche a prezzo di una notazione più complessa, meno intuitiva, e magari non (completamente) posizionale !

NUMERI INTERI (con segno) Rappresentazione in complemento a due idea: cambiare il peso del bit più significativo da +2N-1 a -2N-1 il peso degli altri bit rimane intoccato. Esempi (su 8 bit, MSB ha peso negativo): 0 0000101 = + 5 1 0000101 = -128 + 5 = - 123 1 1111101 = -128 + 125 = - 3

NUMERI INTERI (con segno) Rappresentazione in complemento a due idea: cambiare il peso del bit più significativo da +2N-1 a -2N-1 il peso degli altri bit rimane intoccato. Esempi (su 8 bit, MSB ha peso negativo): 0 0000101 = + 5 1 0000101 = -128 + 5 = - 123 1 1111101 = -128 + 125 = - 3 MSB=0  numero positivo o nullo MSB=1  numero negativo Ma nel secondo caso gli altri bit non sono il valore assoluto!

NUMERI INTERI (con segno) Rappresentazione in complemento a due Intervallo di numeri rappresentabili se MSB=0, è come per i naturali con N-1 bit da 0 a 2N-1-1 Esempio: su 8 bit, [0,+127] se MSB=1, stesso intervallo traslato di -2N-1 da -2N-1 a -1 Esempio: su 8 bit, [-128,-1] Intervallo globale: [-2N-1 , -2N-1-1] su 8 bit, [-128,+127] su 16 bit, [-32768,+32767]

NUMERI INTERI (con segno) Rappresentazione in complemento a due Intervallo di numeri rappresentabili se MSB=0, è come per i naturali con N-1 bit da 0 a 2N-1-1 Esempio: su 8 bit, [0,+127] se MSB=1, stesso intervallo traslato di -2N-1 da -2N-1 a -1 Esempio: su 8 bit, [-128,-1] Intervallo globale: [-2N-1 , -2N-1-1] su 8 bit, [-128,+127] su 16 bit, [-32768,+32767] Lo stesso intervallo prima era tutto sui positivi [0...2N-1] ora è metà sui positivi e metà sui negativi [- 2N-1 ... 2N-1-1] lo zero rientra fra i positivi

CONVERSIONE NUMERO / STRINGA Osservazione: poiché si opera su N bit, questa è in realtà una aritmetica mod 2N La rappresentazione del numero v coincide con quella del numero v + 2N Conseguenza: possiamo in realtà calco-lare la rappresentazione di v’ = v + 2N È un naturale!

CONVERSIONE NUMERO / STRINGA Per calcolare la rappresentazione di v (v<0) si può calcolare quella di v’ = v + 2N Esempio (8 bit, 2N = 256): per calcolare la rappresentazione di -3 calcoliamo quella del naturale 253 -3 = -128 + 125  “11111101” 253  “11111101”

CONVERSIONE NUMERO / STRINGA Problema: dato un numero negativo v, come determinare praticamente la sua rappresentazione in notazione comple-mento a due? Poiché sappiamo convertire un naturale in stringa binaria, il problema diventa: Partendo dalla rappresentazione binaria del valore assoluto |v|, come giungere alla rappresentazione in complemento a due del valore opposto -|v| ?

CONVERSIONE NUMERO / STRINGA Partendo dalla rappresentazione binaria del valore assoluto |v|, come giungere alla rappresentazione in complemento a due del valore opposto -|v| ? Poiché v = - |v| v’ = v + 2N = 2N - |v| tutto sta a riuscire a calcolare 2N - |v|... ...che però richiede una sottrazione!

CONVERSIONE NUMERO / STRINGA Fortunatamente, 2N - |v| è una sottrazione solo in apparenza, in quanto: 2N - |v| = (2N -1)- |v| + 1 Poiché (2N -1) è una sequenza di N “uni”, calcolare (2N -1)- |v| equivale a invertire tutti i bit della stringa che rappresenta |v|: v = -3 |v|  “00000011” (2N -1)- |v|  “11111100” alla fine basta quindi aggiungere 1.

CONVERSIONE NUMERO / STRINGA Algoritmo di complementazione a due Data una stringa di bit che rappresenta il valore v, per ottenere la stringa che rappresenta il valore opposto -v occorre: invertire tutti i bit della stringa data aggiungere 1 al risultato così ottenuto. Esempi v = -3 (3  “00000011” ) “11111101” v = -37 (37  “00100101” ) “11011011” “11111101”  “00000011”  |v| = 3  v = -3

CONVERSIONE STRINGA / NUMERO Problema: data la rappresentazione di un numero intero in notazione complemento a due, determinare il valore del numero Soluzione: applicare la formula oppure: applicare l’algoritmo di complemen-tazione e sfruttare la formula dei naturali per dedurre il valore assoluto del numero.

OPERAZIONI SU NUMERI INTERI Rappresentazione in complemento a due Questa rappresentazione rende possibile fare addizioni e sottrazioni con le usuali regole algebriche Un primo esempio: -5 + 11111011 +3 = 00000011 --- -------- -2 11111110 Funziona!

OPERAZIONI SU NUMERI INTERI Rappresentazione in complemento a due In certi casi occorre però una piccola convenzione: ignorare il riporto Un altro esempio: -1 + 11111111 -5 = 11111011 --- -------- -6 (1)11111010 Funziona… purché si ignori il riporto!

OPERAZIONI SU NUMERI INTERI Rappresentazione in complemento a due Nelle sottrazioni, analogamente, può capitare di dover ignorare il prestito +3 - (1)00000011 - +3 - (1)00000011 - +5 = 00000101 = -5 = 11111011 = -- -------- -- -------- -2 11111110 +8 00001000 Ma.. perché ignorando prestiti e riporti funziona??

OPERAZIONI: PERCHÉ FUNZIONANO Il motivo è semplice: poiché si opera su N bit, questa è in realtà una aritmetica modulare, di modulo 2N ignorando riporti (o inserendo prestiti) si introduce un errore pari a 2N che, quindi, mod 2N scompare! Nota: possono però prodursi errori se viene invaso il bit più significativo

ERRORI NELLE OPERAZIONI In un elaboratore che opera in notazione complemento a due, si ha errore se si supera il massimo intero (positivo o nega-tivo) rappresentabile, cioè se si crea un riporto dal penultimo all’ultimo bit Esempio: 60 + 00111100 75 = 01100011 ----- -------- 135 10011111 (Può capitare solo sommando due positivi o due negativi) Errore! Si è invaso il bit di segno, il risultato è negativo!

SHIFT CON INTERI IN COMPLEMENTO A 2 La semantica delle operazioni di shift Shift Left (SHL) = moltiplicare per 2 Shift Right (SHR) = dividere per 2 è mantenuta in complemento a due? Sì, purché lo Shift Right (SHR) tenga conto del segno, ossia introduca uno 0 da sinistra, se MSB=0 introduca un 1 da sinistra, se MSB=1 Questo shift si chiama Shift Aritmetico

SHIFT CON INTERI IN COMPLEMENTO A 2 Esempio di shift a sinistra: -10 * 4 = -10 SHL 2 11110110 SHL 2 = 11011000  -40 Esempio di shift (aritmetico) a destra: -10 / 4 = -10 SHR 2 11110110 SHR 2 = 11111101  -3 Attenzione: lo Shift Right ha la semantica della divisione intera  il quoziente è il massimo intero minore o uguale a X/Y: non è un semplice troncamento!

IMPLEMENTARE GLI ALGORITMI Conversione da stringa a numero o si applica direttamente la formula oppure se MSB=0 (positivo) si usa sToNum() se MSB=1 (negativo), si sfrutta la relazione v = v’ - 2N, usando sToNum() per ottenere v’, e sottraendo 2N dal risultato. funzione sToInt()

IMPLEMENTARE GLI ALGORITMI Conversione da numero a stringa se il numero è positivo si applica l’algoritmo delle divisioni successive (si ottiene MSB=0) se invece il numero è negativo si applica l’algoritmo delle divisioni successive al numero v’ = v + 2N (ciò assicura MSB=1) funzione intToS()

NUMERI REALI Dominio: R Un soprainsieme degli interi  alcune proprietà degli interi potreb- bero non essere più verificate Un numero reale può non essere finita-mente rappresentabile come stringa di simboli in nessuna base: numeri irrazionali (, e, ...) in alcune basi: numeri razionali periodici

NUMERI REALI La rappresentazione di un numero razio-nale può risultare periodica o meno, a seconda della base adottata In particolare, non è mai periodica se si assume come base il denominatore della sua forma fratta 1/3 = (0.333333333333...)10 = (0.1)3 8/7 = (1.142857142857...)10 = (1.1)7 ...

NUMERI REALI IN DIVERSE BASI Se la rappresentazione di un numero razionale in base B è periodica, allora è periodica anche la rappresentazione dello stesso numero in base B’ = B/k il viceversa vale solo se B’ = Bn Quindi un numero periodico in base 10 è sicuramente: periodico anche in base 2 (perché 10 = 2*5) un numero periodico in base 2 può essere o non essere periodico in base 10… … ma lo è certamente in base 4, 8, 16, ...

NUMERI REALI IN DIVERSE BASI Se la rappresentazione di un numero razionale in base B è periodica, allora è periodica anche la rappresentazione dello stesso numero in base B’ = B/k il viceversa vale solo se B’ = Bn Quindi un numero periodico in base 10 è sicuramente: periodico anche in base 2 (perché 10 = 2*5) un numero periodico in base 2 può essere o non essere periodico in base 10… … ma lo è certamente in base 4, 8, 16, ... Intuitivamente: se non bastavano i fattori primi della base B a esprimere il numero in forma finita, la situazione non può certo migliorare avendo meno fattori a disposizione (B’ = B / k), mentre potrebbe migliorare avendo a disposizione nuovi fattori (B” = r * B)

NUMERI REALI IN DIVERSE BASI Ovviamente, se B’ = Bn, i fattori primi disponibili rimangono gli stessi (cambia solo l’esponente a cui compaiono) e quindi la situazione non può cambiare: se era periodico rimane periodico, se era non periodico rimane non periodico. Se la rappresentazione di un numero razionale in base B è periodica, allora è periodica anche la rappresentazione dello stesso numero in base B’ = B/k il viceversa vale solo se B’ = Bn Quindi un numero periodico in base 10 è sicuramente: periodico anche in base 2 (perché 10 = 2*5) un numero periodico in base 2 può essere o non essere periodico in base 10… … ma lo è certamente in base 4, 8, 16, ...

NUMERI REALI: MANTISSA E RESTO Dato un numero reale V, e fissati: una base B un naturale N è sempre possibile esprimere V come somma di due contributi, di cui il primo costituito da esattamente N cifre: V  m * Besp + r * Besp-N mantissa (n cifre) esponente (intero) resto (reale)

NUMERI REALI: MANTISSA E RESTO Esistono infinite triple m, esp, r che consentono di esprimere, a parità di B e N, lo stesso numero reale V. Ad esempio, se V=31.4357, N=4, B=10:

RAPPRESENTAZIONE NORMALIZZATA Poiché la rappresentazione deve essere unica, occorre fare una scelta Si sceglie la tripla m, esp, r tale che 1/B  m < 1, r<1 Rappresentazione normalizzata

RAPPRESENTAZIONE NORMALIZZATA In pratica, è quella in cui la man-tissa è <1, e la sua prima cifra dopo la virgola è diversa da 0 Poiché la rappresentazione deve essere unica, occorre fare una scelta Si sceglie la tripla m, esp, r tale che 1/B  m < 1, r<1 Rappresentazione normalizzata

NUMERI REALI: IL VINCOLO Un numero reale ha spesso una rappre- sentazione infinita in una data base, ma rappresentare infinite cifre è impossibile Ergo, assumiamo come rappresentazio- ne approssimata del numero reale V il solo contributo m * Besp V  m * Besp Il resto si trascura  Errore di troncamento

NUMERI REALI: LE SCELTE OPERATIVE In pratica dobbiamo stabilire: Quante cifre binarie (bit) per la mantissa? Quante cifre per l’esponente? Espresso come? Come rappresentare il segno del numero? Osservazione: nel caso B=2, la mantissa normalizzata è compresa fra 1/2 e 1: 1/2  m < 1  il primo bit dopo la virgola è sempre 1.

NUMERI REALI: LE SCELTE OPERATIVE In pratica dobbiamo stabilire: Quante cifre binarie (bit) per la mantissa? Quante cifre per l’esponente? Espresso come? Come rappresentare il segno del numero? Osservazione: nel caso B=2, la mantissa normalizzata è compresa fra 1/2 e 1: 1/2  m < 1  il primo bit dopo la virgola è sempre 1. Ma allora… si può evitare di scriverlo esplicitamente! In effetti, un bit prefissato non porta informazione!!

NUMERI REALI: LE SPECIFICHE DEL C Float (IEEE-32; 4 byte) 1 bit per il segno del numero (0 = +, 1 = -) 8 bit per l’esponente esp, codificato con eccesso 126 (28-1-2) valori da 127 a 254  esponenti positivi [1..128] valori da 1 a 125  esponenti negativi [-125..-1] i valori estremi (0 e 255) sono riservati 23 bit per la mantissa m (cioè n=24 bit effettivi, contando l’MSB non rappresentato) dal meno significativo al più significativo

NUMERI REALI: LE SPECIFICHE DEL C Double (IEEE-64; 8 byte) 1 bit per il segno del numero (0 = +, 1 = -) 11 bit per l’esponente esp, codificato con eccesso 1022 (211-1-2) valori da 1023 a 2046  esp. positivi [1..1024] valori da 1 a 1021  esp. negativi [-1021..-1] i valori estremi (0 e 2047) sono riservati 52 bit per la mantissa m (cioè n=53 bit effettivi, contando l’MSB non rappresentato) dal meno significativo al più significativo

NUMERI REALI: LE SPECIFICHE DEL C Casi particolari: float esp=0, m=0 rappresentano 0.0 esp=255, m=0 rappresentano  esp=255, m0 rappresentano un errore double esp=2047, m=0 rappresentano  esp=2047, m0 rappresentano un errore

NUMERI REALI: LE SPECIFICHE DEL C Valori rappresentabili (lato positivo): float [ .1 * 21-126 ... .1111..111*2254-126 ]  [ 2-126 ... 2128 ] cioè [ 1.2 * 10-38 … 3.4 * 1038 ] double [ .1 * 21-1022 ... .1111..111*22046-1022 ]  [ 2-1022 ... 21024 ] cioè [ 1.3 * 10-308 … 0.7 * 10308 ]

NUMERI REALI: CIFRE SIGNIFICATIVE Poiché assumendo V  m * Besp trascu- riamo il resto r * Besp-N, e poiché nella forma nornalizzata r<1, l’errore vale: Eassoluto  Besp-N Esso non è molto significativo in sé: lo è di più se rapportato al valore del numero Erelativo  Besp-N / (m * Besp) da cui, poiché 1/B  m < 1, Erelativo  Besp-N / Besp-1 = B1-N

NUMERI REALI: CIFRE SIGNIFICATIVE Se dunque Erelativo  B1-N , le cifre decimali significative risultano: float N=24 Er  2-23 = 10-23*log2 = 10-7 circa 7 cifre decimali significative double N=53 Er  2-52 = 10-52*log2 = 10-15 circa 15 cifre decimali significative

NUMERI REALI: CIFRE SIGNIFICATIVE Se dunque Erelativo  B1-N , le cifre decimali significative risultano: float N=24 Er  2-23 = 10-23*log2 = 10-7 circa 7 cifre decimali significative double N=53 Er  2-52 = 10-52*log2 = 10-15 circa 15 cifre decimali significative Epsilon di macchina: il più piccolo float che la macchina distingue come diverso da 0 il più piccolo double distin-guibile da 0

Rappresentazione come float di V = 1.0 NUMERI REALI: ESEMPIO 1 Rappresentazione come float di V = 1.0 rappr. normalizzata: V = 1.010 = 0.12 * 21 segno (1 bit): 0 mantissa (24 bit): .10000000 00000000 00000000 esponente (8 bit con eccesso 126) esp=1  126+1 = 127  01111111 in memoria:

Rappresentazione come float di V = 5.875 NUMERI REALI: ESEMPIO 2 Rappresentazione come float di V = 5.875 rappr. normalizzata: V = 101.1112 = .1011112 * 23 segno (1 bit): 0 mantissa (24 bit): .10111100 00000000 00000000 esponente (8 bit con eccesso 126) esp=3  126+3 = 129  10000001 in memoria:

Rappresentazione come float di V = -29.1875 NUMERI REALI: ESEMPIO 3 Rappresentazione come float di V = -29.1875 rappr. normalizzata: V = - .1110100112 *25 segno (1 bit): 1 mantissa (24 bit): .11101001 10000000 00000000 esponente (8 bit con eccesso 126) esp=5  126+5 = 131  10000011 in memoria:

Rappresentazione come float di V = 0.110 NUMERI REALI: ESEMPIO 4 Rappresentazione come float di V = 0.110 rappr. normalizzata: V =.0(0011)2 periodico! segno (1 bit): 0 mantissa (24 bit): .11001100 11001100 11001100 esponente (8 bit con eccesso 126) esp=-3  126-3 = 123  01111011 in memoria:

Rappresentazione come float di V = 0.110 NUMERI REALI: ESEMPIO 4 Rappresentazione come float di V = 0.110 rappr. normalizzata: V =.0(0011)2 periodico! segno (1 bit): 0 mantissa (24 bit): .11001100 11001100 11001101 esponente (8 bit con eccesso 126) esp=-3  126-3 = 123  01111011 in memoria: Errore di troncamento o si tronca o si arrotonda il C arrotonda

Rappresentazione come float di V = 0.1510 NUMERI REALI: ESEMPIO 5 Rappresentazione come float di V = 0.1510 rappr. normalizzata: V =.00(1001)2 periodico! segno (1 bit): 0 mantissa (24 bit): .10011001 10011001 10011010 esponente (8 bit con eccesso 126) esp=-2  126-2 = 124  01111100 in memoria:

Rappresentazione come float di V = -1/310 NUMERI REALI: ESEMPIO 6 Rappresentazione come float di V = -1/310 rappr. normalizzata: V = -.(01)2 periodico! segno (1 bit): 1 mantissa (24 bit): .10101010 10101010 10101011 esponente (8 bit con eccesso 126) esp=-1  126-1 = 125  01111101 in memoria:

CONVERSIONE STRINGA / NUMERO Problema: data la rappresentazione di un numero reale in una certa base, determinare il valore del numero Soluzione: applicare la formula Bisogna considerare anche potenze negative di B, con le cifre dopo la virgola.

CONVERSIONE STRINGA / NUMERO Esempio: calcolare il valore rappresentato dalla stringa 1001.112 Soluzione: si sommano i singoli contributi V = 23 + 20 + 2-1 + 2-2 = 9.7510 Operativamente, con i naturali si valutava il polinomio con il metodo di Horner. E adesso?

CONVERSIONE STRINGA / NUMERO Conviene separare il calcolo della parte intera da quello della parte frazionaria: Per il calcolo del valore della parte intera si può usare ancora l’algoritmo di Horner. Per il calcolo del valore della parte frazionaria si può adottare un algoritmo analogo.

CONVERSIONE STRINGA / NUMERO Calcolo del valore della parte frazionaria: L’algoritmo di Horner raccoglieva via via il fattore B, questo raccoglie il fattore 1/B. Esempio: .11012 (valuta da destra a sinistra) V = (((((1 / 2 + 0) / 2) + 1) / 2 + 1) / 2) = 0.812510

CONVERSIONE NUMERO / STRINGA Per convertire un numero in una stringa di cifre, l’essenziale è riuscire a “isolare” e ricavare le singole cifre. Nel caso dei naturali, lo si fa con l’algoritmo delle divisioni successive: dk = vk % B il quoziente vk+1 = vk / B consente di iterare Per la parte frazionaria occorre dunque un algoritmo analogo.

CONVERSIONE NUMERO / STRINGA Algoritmo delle moltiplicazioni successive si moltiplica v per B la parte intera che si genera costituisce la cifra più significativa la parte frazionaria itera il procedimento se prima o poi la parte frazionaria si azzera, il numero è rappresentabile in forma finita in tale base; se invece si rigenera la stessa serie di cifre, siamo di fronte a un numero periodico in tale base.

Calcolare la rappresentazione binaria del numero V=0.87510 UN ESEMPIO Calcolare la rappresentazione binaria del numero V=0.87510 .875 * 2 = 1.75 parte intera = 1, parte frazionaria restante = .75 .75 * 2 = 1.5 parte intera = 1, parte frazionaria restante = .5 .5 * 2 = 1.0 parte intera = 1, parte frazionaria restante = .0 Rappresentazione risultante: .1112 (non periodico)

Calcolare la rappresentazione binaria del numero V=0.1510 UN ALTRO ESEMPIO Calcolare la rappresentazione binaria del numero V=0.1510 .15 * 2 = 0.3  parte intera = 0 .3 * 2 = 0.6  parte intera = 0 .6 * 2 = 1.2  parte intera = 1 .2 * 2 = 0.4  parte intera = 0 .4 * 2 = 0.8  parte intera = 0 .8 * 2 = 1.6  parte intera = 1 .6 * 2 = 1.2 si ripete la sequenza!! Rappresentazione (periodica): .00(1001)2

DENTRO LA MACCHINA C E se volessimo “spiare” dentro la macchi-na virtuale C per vedere la rappresenta-zione fisica dei numeri? Occorre ricavare l’indirizzo della variabile esplorare quell’area di memoria byte per byte, per tanti byte quanta la dimensione di quel tipo di dato (es: float = 4 byte) visualizzare ogni byte.

DENTRO LA MACCHINA C Un programma: main() { cast: ci serve un puntatore a byte, che in C si esprime come “unsigned char” Un programma: main() { float x; int i; unsigned char* p = (unsigned char*) &x; printf("Float: "); scanf("%f",&x); printf("\nRappr. interna di %f:\n", x); for (i=0; i<sizeof(x); i++) printf("Byte %i:\t%X\n",i, p[i] ); printf("\n"); } i-esimo byte sizeof: dà la dimensione in byte di quella variabile esadecimale

OPERAZIONI FRA REALI & ERRORI Negli interi, si possono creare errori nelle operazioni, ma gli operandi sono comunque rappresentati esattamente Nei reali, invece, già gli stessi operandi possono essere affetti da errore, a causa dell’impossibilità di rappresentare le infinite cifre dei numeri periodici e irrazionali: è l’errore di troncamento. Errore di troncamento = ogni qual volta il numero di cifre disponibili è insufficiente.

Esempi (mantissa di 8 bit, per semplicità) ERRORE DI TRONCAMENTO Si manifesta quando il numero è periodico il numero non è periodico ma ha troppe cifre il risultato di un’operazione, a causa un ripor-to, richiede troppe cifre Esempi (mantissa di 8 bit, per semplicità) 15.810 = .1111110011001100... * 24 (è 15.75) 301.510 = .10010110012 * 29 (è 300) 15110 + 16010 = = .10010111 * 28 + .10100000 * 28 = = .100110111 * 29 (è 310)

OPERAZIONI FRA REALI & ERRORI Vi sono poi altre due sorgenti di errore: l’errore di incolonnamento è causato dalla necessità di incolonnare i numeri per poterli sommare o sottrarre l’errore di cancellazione è la conseguenza finale della presenza, a monte, di errori di troncamento, che possono far sì che alcune cifre del risultato non siano affidabili, ovvero siano “virtualmente cancellate” si manifesta sottraendo numeri simili fra loro.

ERRORE DI INCOLONNAMENTO L’errore di incolonnamento è causato dalla necessità di incolonnare i numeri per poterli sommare o sottrarre per incolonnare due numeri che, in forma normalizzata, hanno esponente diverso occorre necessariamente “de-normalizzarne” uno si allinea quello di valore assoluto minore a quello di valore assoluto maggiore ciò causa una perdita di cifre significative nel numero che viene “de-normalizzato”.

ERRORE DI INCOLONNAMENTO Esempio: 96.5 + 1.75 Ipotesi: mantissa di 8 bit (per semplicità) 96.510 =.110000012 * 27 (senza errore) 1.7510 =.111000002 * 21 (senza errore) Somma: .110000012 * 27 + .110000012 * 27 + .111000002 * 21 = .000000112 * 27 = .110001002 * 27 cifre perse: è l’errore di incolonnamento È 98, non 98.25 come doveva!

ERRORE DI CANCELLAZIONE L’errore di cancellazione è può presentar-si quando si sottraggono numeri assai simili fra loro accade solo se in almeno uno dei due operan-di, all’inizio, vi è stato errore di troncamento consiste nel fatto che si introducono zeri da destra per normalizzare il risultato, ma quegli zeri non sono significativi se ci fossero state le cifre perse all’inizio a causa del troncamento, il risultato sarebbe stato diverso.

ERRORE DI CANCELLAZIONE Esempio: 15.8 + 15.5 Ipotesi: mantissa di 8 bit (per semplicità) 15.810 =.111111002 * 24 (con errore tronc.) 15.510 =.111110002 * 24 (senza errore) Differenza: .111111002 * 24 - .111110002 * 24 = .000001002 * 24 = . 100000002 * 2-1 cifre cancellate: è l’errore di cancellazione Sono 0 solo perché abbiamo troncato 15.8 all’inizio: avrebbero dovuto essere 11001

Esempio (mantissa di 8 bit, per semplicità) ERRORI: CONSEGUENZE A causa di questi errori, la proprietà associativa può non essere più verificata Esempio (mantissa di 8 bit, per semplicità) X = 0,75  .11000000 * 20 (senza errori) Y = 65,6  .10000011 * 27 (err. troncamento) Z = 64,0  .10000000 * 27 (senza errori) si ha che (X + Y) - Z è diverso da X + (Y - Z)

ERRORI: CONSEGUENZE (X + Y) - Z è diverso da X + (Y - Z)

ACCUMULAZIONE DI ERRORI La presenza di errori che si accumulano può portare a risultati totalmente assurdi Esempio: Calcolo di  con l’algoritmo di Euclide Una circonferenza di raggio 1 è lunga 2, che può essere approssimata: dall’esterno, dal perimetro del poligono regolare di n lati circoscritto dall’interno, dal perimetro del poligono regolare di n lati inscritto

ACCUMULAZIONE DI ERRORI Valgono le relazioni: ln = lato del poligono di n lati inscritto Ln = lato del poligono di n lati circoscritto = 2 l /  (4 - l2)

ACCUMULAZIONE DI ERRORI Una funzione che implementa l’algoritmo: void pigrecoFloat(void) { float eps, LN, smpinf, smpsup, nlati, OC2, diff; printf("Calcolo di pigreco con FLOAT. " "Precisione [1e-8] ? "); scanf("%f", &eps); nlati = 4.0; LN = sqrt(2.0); do { OC2 = sqrt(4.0 - LN * LN); nlati *= 2.0; diff = 2.0 - OC2; LN = sqrt(diff); smpinf = LN * nlati / 2.0; smpsup = LN * nlati / OC2; printf("nl=%10.0f d2=%f piInf=%f piSup=%f\n", nlati, OC2, smpinf, smpsup); } while ((smpsup-smpinf >= eps) && (nlati < 1e+19)); }

ACCUMULAZIONE DI ERRORI … e il suo output: Calcolo di pigreco con FLOAT. Precisione ? 1E-8 nl= 8 d2=1.414214 piInf=3.061467 piSup = 4.329569 nl= 16 d2=1.847759 piInf=3.121444 piSup = 3.378627 nl= 32 d2=1.961571 piInf=3.136546 piSup = 3.197995 nl= 64 d2=1.990369 piInf=3.140333 piSup = 3.155528 nl= 128 d2=1.997591 piInf=3.141286 piSup = 3.145074 nl= 256 d2=1.999398 piInf=3.141519 piSup = 3.142465 nl= 512 d2=1.999849 piInf=3.141208 piSup = 3.141444 nl= 1024 d2=1.999962 piInf=3.142451 piSup = 3.142510 nl= 2048 d2=1.999991 piInf=3.142451 piSup = 3.142466 nl= 4096 d2=1.999998 piInf=3.162278 piSup = 3.162282 nl= 8192 d2=1.999999 piInf=3.162278 piSup = 3.162279 nl=16384 d2=2.000000 piInf=2.828427 piSup = 2.828427 nl=32768 d2=2.000000 piInf=0.000000 piSup = 0.000000

CONVERSIONE DA INTERI A REALI Nelle espressioni che coinvolgono interi e reali, i numeri interi devono essere con-vertiti in rappresentazione reale per poter eseguire le operazioni Non si può semplicemente “spostare la virgola”, perché la rappresentazione in complemento a due non è posizionale Esempio: N = -8 (intero, 1 byte) 11111000 R = -8.0 = .1*23 1 10000001 0000000 segno mantissa esp (126+3)

ESERCIZIO Dire come vengono svolte le seguenti espressioni, calcolandole passo passo Ipotesi: interi rappresentati in complemento a due su un byte (8 bit  da -128 a +127) reali rappresentati su due byte (1 bit di segno, 8 di esponente con eccesso 126, 7 di mantissa) Esercizio int i=10; float a=0.6, b, c; b = a + i - 8; c = a + (i - 8);

FUNZIONI DI CONVERSIONE STANDARD La libreria standard stdlib fornisce quasi tutte le funzioni di conversione già pronte da stringa a numero atoi() da stringa a intero atol() da stringa a long atof() da stringa a double da numero a stringa (solo Turbo C) itoa() da intero a stringa ltoa() da long a stringa fcvt() da double a stringa Il C standard usa sprintf(), che vedremo più avanti.