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,
spesso assai
 Dominio: che rendono
N = { 0,1,2,3,
…} complessa
l'esecuzione dei calcoli
 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'effettuazione 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:
n1
v   dk B
k
k 0
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:
Stringa
“12”
“12”
“12”
“12”
Base
quattro
otto
dieci
sedici
Alfabeto
{0,1,2,3}
{0,1,...,7}
{0,1,...,9}
{0,..,9, A,., F}
Calcolo valore
4*1+2
8*1+2
10 * 1 + 2
16 * 1 + 2
Valore
sei
dieci
dodici
diciotto
NOTAZIONE POSIZIONALE
 Ogni numero può essere espresso, in
modo univoco, in una qualunque base
 Esempi:
Numero
venti
venti
venti
venti
Base
due
otto
dieci
sedici
Alfabeto
Rappresentazione
{0,1}
“10100”
{0,1,...,7}
“24”
{0,1,...,9}
“20”
{0,..,9, A,., F}
“14”
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:
Conversione
da stringa a numero
 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 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
n1
v   dk B
k
k 0
Stringa
“10100”
“12”
“1A”
Base
due
dieci
sedici
Alfabeto
Calcolo valore
Valore
{0,1}
1 * 2 4 + 1 * 22
venti
{0,1,...,9}
1 * 101 + 2 * 100 dodici
{0,..,9, A,., F} 1 * 161 + 10 * 160 ventisei
CONVERSIONE NUMERO / STRINGA
 Problema: dato un numero, determinare
la sua rappresentazione
 Soluzione: dipende se la rappresentazione 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
n1
v   dk B
k
v è noto,
le cifre dk vanno calcolate
k 0
= d0 + B * ( d1 + B * ( d2 + B * ( d3 + ... )))
CONVERSIONE NUMERO / STRINGA
n1
v   dk B
k
k 0
= d0 + B * ( d1 + B * ( d2 + B * ( d3 + ... )))
 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 significativa (LSB) alla più significativa (MSB)
CONVERSIONE NUMERO / STRINGA
n1
v   dk B
k
k0
= d0 + B * ( d1 + B * ( d2 + B * ( d3 + ... )))
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 significativa (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
Numero
quattordici
undici
sessantatre
sessantatre
Base
4
2
10
16
Calcolo valore
14 / 4 = 3 con resto 2
3 / 4 = 0 con resto 3
11 / 2 = 5 con resto 1
5 / 2 = 2 con resto 1
2 / 2 = 1 con resto 0
1 / 2 = 0 con resto 1
63 / 10 = 6 con resto 3
6 / 10 = 0 con resto 6
63 / 16 = 3 con resto 15
3 / 16 = 0 con resto 3
Stringa
“32”
“1011”
“63”
“3F”
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
8 = 23
 Esempio:
1 cifra ottale = 3 cifre binarie
 B1 = 2  “01000011”
 B2 = 8 = 23 = (B1)3  “103”
01.000.011
 B3 = 10  “67”
 B4 = 16 = 24 = (B1)4  “43”
0100.0011
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 rappresentazione 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
Numero
uno
due
tre
quattro
cinque
otto
dieci
quindici
sedici
trentuno
trentadue
cento
duecentocinquantacinque
Rappr. Base 2
1
10
11
100
101
1000
1010
1111
10000
11111
100000
1100100
11111111
Rappr. Base 8
1
2
3
4
5
10
12
17
20
37
40
144
377
Rappr. Base 16
1
2
3
4
5
8
A
F
10
1F
20
64
FF
OPERAZIONI IN NOTAZIONE POSIZIONALE
 Tutte le notazioni posizionali usano le
stesse regole per le operazioni, indipendentemente dalla base adottata
 Esempi di somme e sottrazioni:
15 + 0000 1111 + 0F +
21 = 0001 0101 = 15 =
------------------------36
0010 0100
24
36 - 0010 0100 - 24 21 = 0001 0101 = 15 =
-----------------------15
0000 1111
0F
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:
base dieci:
base due:
base due:
184 *
1832 /
1011 *
1111 /
10
10
2
2
= 1840
=
183 _
= 10110
=
111 _
Divisione
intera
OPERAZIONI IN NOTAZIONE POSIZIONALE
 Due mosse elementari:
 Shift Left (SHL)
15 * 4 =
0000 1111 SHL 2 =
----------------------------60
0011 1100
 Shift Right (SHR)
25 / 8 =
0001 1001 SHR 3 =
----------------------------3
0000 0011
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
decimale
176 +
84 =
---260
binario
1011 0000+
0101 0100=
---------1 0000 0100
Praticamente
decimale
176 +
84 =
---004
binario
1011 0000+
0101 0100=
---------0000 0100
 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
n1
v   dk B
k 0
k
le cifre dk sono note,
il valore v va calcolato
= d0 + B * ( d1 + B * ( d2 + B * ( d3 + ... )))
 richiede la valutazione di un
polinomio  Metodo di Horner
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
return
('0'<= ch)&&(ch <= '9')
ch - '0' :
('a'<= ch)&&(ch <= 'f')
ch - 'a' + 10 :
('A'<= ch)&&(ch <= 'F')
ch - 'A' + 10 : BOH;
}
ch) {
?
?
?
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
n1
v   dk B
k
v è noto,
le cifre dk vanno calcolate
k 0
= d0 + B * ( d1 + B * ( d2 + B * ( d3 + ... )))
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:
la passiamo come parametro
(passa per riferimento)
ipotesi: inizialmente è vuota
ed è sufficientemente lunga
 stringa di simboli, s
 (lunghezza della stringa)
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,scrivere
charuna
s[])
{
occorre
funzione
char convertiCifra(unsigned
<ripeti>
int)
<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 tempooccorre
che v>0
> una procedura
scrivere
}
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 posizione 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 posizione 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 elaboratore 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
Rappresentazione in modulo
-5
--Difetti:
0
0 0000101
e segno
1 0000101
---------1 0001010
 due diverse rappresentazioni per lo zero
+ 0 = 00000000 Cos’è
- 0 =questa
10000000
roba???
(+5) + (-5) = -10 ???
 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
MSB=0
 numero
o nullo
 idea: cambiare
il peso
del bitpositivo
più
MSB=1 
numero
negativo
N-1
N-1
significativo da +2 a -2
Ma nel secondo caso gli altri bit
il valore intoccato.
assoluto!
 il peso degli non
altrisono
bit rimane
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
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
complemento a due
Lo stessoinintervallo
N-1]

prima
era
tutto
sui
positivi
[0...2
Intervallo di numeri rappresentabili
 ora è metà sui positivi e metà sui
 se MSB=0,negativi
è come[- per
i naturali
2N-1 ...
2N-1-1] con N-1 bit
fra i positivi
 da 0 a 2N-1lo-1zero rientra
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]
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à calcolare la rappresentazione di v’ = v + 2N
v  dn1 B
n 2
n1
  dk B
v'  dn1B
k
k0
n1
È un naturale!
n 2
  dk B
k
k0
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 complemento 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
v  dn1 B
n 2
n1
  dk B
k
k0
 oppure: applicare l’algoritmo di complementazione 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 +
+3 =
---2
11111011
00000011
-------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 +
-5 =
---6
11111111
11111011
-------(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 +5 =
--2
(1)00000011 00000101 =
-------11111110
+3 -5 =
-+8
(1)00000011 11111011 =
-------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 negativo) rappresentabile, cioè se si crea un
riporto dal penultimo all’ultimo bit
 Esempio:
60 +
75 =
----135
00111100
01100011
-------10011111
Errore!
Si è invaso il bit di
segno, il risultato è
negativo!
(Può capitare solo sommando due positivi o due negativi)
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
v  dn1 B
n 2
n1
 oppure
  dk B
k
k0
 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 potrebbero non essere più verificate
 Un numero reale può non essere finitamente rappresentabile come stringa di
simboli
 in nessuna base: numeri irrazionali (, e, ...)
 in alcune basi: numeri razionali periodici
NUMERI REALI
 La rappresentazione di un numero razionale 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
se non bastavano i fattori primi
 Intuitivamente:
Quindi
della base B a esprimere il numero in forma finita,
 un numero periodico in base 10 è sicuramente:
la situazione non può certo migliorare avendo meno
periodico anche in base 2 (perché 10 = 2*5)
fattori a disposizione (B’ = B / k), mentre potrebbe
 un numero
periodico
in base 2 può
essere
o
migliorare
avendo
a disposizione
nuovi
fattori
periodico in base 10…
(B” non
= r * essere
B)
 … ma lo è certamente in base 4, 8, 16, ...
NUMERI REALI IN DIVERSE BASI
Ovviamente, se B’ = Bn, i fattori primi disponibili
gli stessi (cambia
 Serimangono
la rappresentazione
disolo
un l’esponente
numero a cui
compaiono) e quindi la situazione non può
razionale in base B è periodica, allora
cambiare: se era periodico rimane periodico, se era
è non
periodica
rappresentazione
periodicoanche
rimanela
non
periodico.
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:
314,3
31,43
3,143
,3143
,0314
,0031
,0003
,0000
Scomposizione
* 10-1 + 570,
* 100 + 57,
* 101 +
5,7
2
* 10 +
,57
3
* 10 +
,357
4
* 10 +
,4357
* 105 +
,14357
* 106 +
,314357
*
*
*
*
*
*
*
*
-1-4
10
100-4
101-4
102-4
103-4
104-4
105-4
106-4
m
m=314.3
m=31.43
m=3.143
m=.3143
m=.0314
m=.0031
m=.0003
m=.0000
r
r=570
r=57
r=5.7
r=.57
r=.357
r=.4357
r=.14357
r=.314357
esp
esp=-1
esp =0
esp =1
esp =2
esp =3
esp =4
esp =5
esp =6
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
Scomposizione
.....
1
3,143 * 10 +
5,7
,3143 * 102 +
,57
,0314 * 103 +
,357
.....
* 101-4
* 102-4
* 103-4
m
....
m=3.143
m=.3143
m=.0314
....
r
....
r=5.7
r=.57
r=.357
....
esp
....
esp =1
esp =2
esp =3
....
RAPPRESENTAZIONE NORMALIZZATA
In pratica, è quelladeve
in cui essere
la man Poiché la rappresentazione
tissa è <1, e la sua prima cifra
unica, occorre fare una scelta
dopo la virgola è diversa da 0
 Si sceglie la tripla m, esp, r tale che
1/B  m < 1,
r<1
Rappresentazione normalizzata
Scomposizione
.....
1
3,143 * 10 +
5,7
,3143 * 102 +
,57
,0314 * 103 +
,357
.....
* 101-4
* 102-4
* 103-4
m
....
m=3.143
m=.3143
m=.0314
....
r
....
r=5.7
r=.57
r=.357
....
esp
....
esp =1
esp =2
esp =3
....
NUMERI REALI: IL VINCOLO
 Un numero reale ha spesso una rappresentazione infinita in una data base, ma
rappresentare infinite cifre è impossibile
 Ergo, assumiamo come rappresentazione 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?
Ma allora…
si può
evitare di scriverlo
esplicitamente!
In effetti, un
 Come rappresentare
il bit
segno del numero?
prefissato non porta informazione!!
 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 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 byte 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 byte 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=0, m=0
rappresentano 0.0
 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
Cifre significative
 Poiché assumendo V  m * Besp trascuriamo 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
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
Cifre significative Epsilon di macchina: il più
float
chedecimali
la macchina
Se dunque Erelativo  piccolo
B1-N , le
cifre
distingue come diverso da 0
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
il più piccolo
double distinguibile da 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
segno
0
esponente
0111 1111
mantissa normalizzata (23 bit, MSB escluso)
000 0000 0000 0000 0000 0000
in memoria:
byte 1
0011 1111
byte 2
1000 0000
byte 3
0000 0000
byte 4
0000 0000
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
segno
0
esponente
1000 0001
mantissa normalizzata (23 bit, MSB escluso)
011 1100 0000 0000 0000 0000
in memoria:
byte 1
01000000
byte 2
1011 1100
byte 3
0000 0000
byte 4
0000 0000
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
segno
1
esponente
1000 0011
mantissa normalizzata (23 bit, MSB escluso)
110 1001 1000 0000 0000 0000
in memoria:
byte 1
1100 0001
byte 2
1110 1001
byte 3
1000 0000
byte 4
0000 0000
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
segno
0
esponente
0111 1011
mantissa normalizzata (23 bit, MSB escluso)
100 1100 1100 1100 1100
in memoria:
byte 1
0011 1101
byte 2
1100 1100
byte 3
1100 1100
byte 4
1100 1100
NUMERI REALI: ESEMPIO 4
Rappresentazione comeErrore
float di
V = 0.110
di troncamento
o si tronca periodico!
o si arrotonda
 rappr. normalizzata: V =.0(0011)
2
il C arrotonda
 segno (1 bit):
0
 mantissa (24 bit):
.11001100 11001100 11001101
 esponente (8 bit con eccesso 126)
esp=-3  126-3 = 123  01111011
segno
0
esponente
0111 1011
mantissa normalizzata (23 bit, MSB escluso)
100 1100 1100 1100 1101
in memoria:
byte 1
0011 1101
byte 2
1100 1100
byte 3
1100 1100
byte 4
1100 1101
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
segno
0
esponente
0111 1100
mantissa normalizzata (23 bit, MSB escluso)
001 1001 1001 1001 1001 1010
in memoria:
byte 1
0011 1110
byte 2
0001 1001
byte 3
1001 1001
byte 4
1001 1010
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
segno
1
esponente
0111 1101
mantissa normalizzata (23 bit, MSB escluso)
010 1010 1010 1010 1010 1011
in memoria:
byte 1
1011 1110
byte 2
1010 1010
byte 3
1010 1010
byte 4
1010 1011
CONVERSIONE STRINGA / NUMERO
 Problema: data la rappresentazione di un
numero reale in una certa base,
determinare il valore del numero
 Soluzione: applicare la formula
v
n1
d B
k  m
k
k
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
v
n1
d B
k  m
k
k
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:
v
1
n1
d B  d B
k
k  m
k
k 0
k
k
 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:
1
d B
k  m
k
k
 ((..((d m / B)  dm 1 )/ B) ...d1 ) / B)
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.
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)
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 macchina virtuale C per vedere la rappresentazione fisica dei numeri?
p
 Occorre
x
 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.
&x
9A
99
19
3E
Esempio: x = 0,15
DENTRO LA MACCHINA C
Un programma:
main() {
cast: ci serve un puntatore a
byte, che in C si esprime
come “unsigned char”
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.
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 riporto, richiede troppe cifre
 Esempi (mantissa di 8 bit, per semplicità)
 15.810 = .1111110011001100... * 24
 301.510 = .10010110012 * 29
 15110 + 16010 =
= .10010111 * 28 + .10100000 * 28 =
= .100110111 * 29
(è 15.75)
(è 300)
(è 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 =
cifre perse:
è l’errore di
incolonnamento
.110001002 * 27
È 98, non 98.25 come doveva!
ERRORE DI CANCELLAZIONE
L’errore di cancellazione è può presentarsi quando si sottraggono numeri assai
simili fra loro
 accade solo se in almeno uno dei due operandi, 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:
cifre cancellate:
è l’errore di
.111111002 * 24 cancellazione
4
.111110002 * 2 =
.000001002 * 24 = . 100000002 * 2-1
Sono 0 solo perché abbiamo troncato 15.8
all’inizio: avrebbero dovuto essere 11001
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
Primo caso:
(X + Y) - Z
Prima operazione: A = X + Y
.11000000 * 20 +
.10000011 * 27 =
.00000001 * 27 +
.10000011 * 27 =
.10000100 * 27  A
(err. incolonnamento)
Seconda operazione: R = A - Z
.10000100 * 27 .10000000 * 27 =
.00000100 * 27 =
.100????? * 22 =
.10000000 * 22  R
(da rinormalizzare)
(errore cancellazione)
R = .10000000 * 22
X + (Y - Z)
Secondo caso: X + (Y - Z)
Prima operazione: A = Y - Z
.10000011 * 27 .10000000 * 27 =
.00000011 * 27 =
.11?????? * 21 =
.11000000 * 21  A
(da rinormalizzare)
(errore cancellazione)
Seconda operazione: R = X + A
.11000000 * 20 +
.11000000 * 21 =
.01100000 * 21 +
.11000000 * 21 =
1.00100000 * 21
.10010000 * 22  R
(err. incolonnamento)
(da rinormalizzare)
(err. tronc. potenziale)
R = .10010000 * 22
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)
Ln
ln
Ln = lunghezza lato poligono
circoscritto di n lati
ln = lunghezza lato poligono
inscritto di n lati
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
nl=
8 d2=1.414214
nl=
16 d2=1.847759
nl=
32 d2=1.961571
nl=
64 d2=1.990369
nl= 128 d2=1.997591
nl= 256 d2=1.999398
nl= 512 d2=1.999849
nl= 1024 d2=1.999962
nl= 2048 d2=1.999991
nl= 4096 d2=1.999998
nl= 8192 d2=1.999999
nl=16384 d2=2.000000
nl=32768 d2=2.000000
FLOAT. Precisione ? 1E-8
piInf=3.061467 piSup = 4.329569
piInf=3.121444 piSup = 3.378627
piInf=3.136546 piSup = 3.197995
piInf=3.140333 piSup = 3.155528
piInf=3.141286 piSup = 3.145074
piInf=3.141519 piSup = 3.142465
piInf=3.141208 piSup = 3.141444
piInf=3.142451 piSup = 3.142510
piInf=3.142451 piSup = 3.142466
piInf=3.162278 piSup = 3.162282
piInf=3.162278 piSup = 3.162279
piInf=2.828427 piSup = 2.828427
piInf=0.000000 piSup = 0.000000
CONVERSIONE DA INTERI A REALI
 Nelle espressioni che coinvolgono interi e
reali, i numeri interi devono essere convertiti 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)
 R = -8.0 = .1*23
segno
11111000
1 10000001 0000000
esp (126+3)
mantissa
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()
 atol()
 atof()
da stringa a intero
da stringa a long
da stringa a double
 da numero a stringa (solo Turbo C)
 itoa()
 ltoa()
 fcvt()
da intero a stringa
da long a stringa
da double a stringa
Il C standard
usa sprintf(),
che vedremo
più avanti.