1 Rappresentare le informazioni Esempio: numeri interi assoluti
1 Rappresentare le informazioni Esempio: numeri interi assoluti
1 Rappresentare le informazioni Esempio: numeri interi assoluti
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
<strong>Rappresentare</strong> <strong>le</strong> <strong>informazioni</strong><br />
con un insieme limitato di simboli (detto alfabeto A)<br />
in modo non ambiguo (algoritmi di traduzione tra codifiche)<br />
<strong>Esempio</strong>: <strong>numeri</strong> <strong>interi</strong> <strong>assoluti</strong><br />
Codifica decima<strong>le</strong> (in base dieci)<br />
A = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }<br />
“sette” : 7<br />
“ventitre” : 23<br />
“centotrentotto” : 138<br />
Notazione posiziona<strong>le</strong><br />
dalla cifra più significativa a quella meno significativa<br />
ogni cifra corrisponde a una diversa potenza di dieci<br />
1
Notazione posiziona<strong>le</strong>: permette di rappresentare<br />
un qualsiasi numero natura<strong>le</strong> (intero non negativo)<br />
nel modo seguente:<br />
la sequenza di cifre c i :<br />
c n c n-1 … c 1<br />
rappresenta in base B ≥ 2 il valore:<br />
c n ×B n-1 + c n-1 ×B n-2 + … + c 1 ×B 0<br />
avendosi: c i ∈{0, 1, 2, …, B-1} per ogni 1 ≤ i ≤ n<br />
La notazione decima<strong>le</strong> tradiziona<strong>le</strong> è di tipo<br />
posiziona<strong>le</strong> (ovviamente con B = dieci)<br />
Base generica: B<br />
A = { ... }, con |A| = B, sequenze di n simboli (cifre)<br />
c n c n-1 ... c 2 c 1 = c n x B n-1 + … + c 2 x B 1 + c 1 x B 0<br />
Con n cifre rappresentiamo B n <strong>numeri</strong>: da 0 a B n -1<br />
“ventinove” in varie basi<br />
B = otto A={0,1,2,3,4,5,6,7} 29 10 = 35 8<br />
B = cinque A={0,1,2,3,4} 29 10 = 104 5<br />
B = tre A={0,1,2} 29 10 = 1002 3<br />
B = sedici A={0,1,...,8,9,A,B,C,D,E,F} 29 10 = 1D 16<br />
Codifiche notevoli<br />
Esadecima<strong>le</strong> (sedici), otta<strong>le</strong> (otto), binaria (due)<br />
2
Usata dal calcolatore per tutte <strong>le</strong> <strong>informazioni</strong><br />
B = due, A = { 0, 1 }<br />
BIT (“BInary digIT”):<br />
unità ELEMENTARE di informazione<br />
Dispositivi che assumono due stati<br />
Ad esempio due valori di tensione V A e V B<br />
Numeri binari naturali:<br />
la sequenza di bit b i (cifre binarie):<br />
b n b n-1 … b 1 , avendosi b i ∈ {0, 1}<br />
rappresenta in base 2 il valore:<br />
b n ×2 n -1 + b n-1 ×2 n-2 + … + b 1 ×20<br />
Il calcolatore tratta diversi tipi di dati<br />
(<strong>numeri</strong>, caratteri, ecc.) tutti rappresentati<br />
con la codifica binaria<br />
Prob<strong>le</strong>ma: assegnare un codice univoco a<br />
tutti gli oggetti compresi in un insieme<br />
predefinito.<br />
<strong>Esempio</strong>:<br />
associare un codice binario ai giorni della settimana<br />
3
Quanti oggetti diversi posso codificare con<br />
paro<strong>le</strong> binarie composte da k bit?<br />
1 bit: 2 1 = 2 stati (0, 1) ⇒ 2 oggetti<br />
2 bit: 2 2 = 4 stati (00, 01, 10, 11) ⇒ 4 oggetti<br />
3 bit: 2 3 = 8 stati (000, 001, 010, 011, 100, 101, 110,<br />
111) ⇒ 8 oggetti<br />
…<br />
k bit: 2 k stati ⇒ 2 k oggetti<br />
Se passiamo da una parola binaria di k bit ad<br />
una parola di k+1 bit si raddoppia il numero<br />
di oggetti che si possono rappresentare (2 k+1 )<br />
Quanti bit mi servono per codificare N<br />
oggetti?<br />
N ≤ 2 k ⇒ k ≥ log 2 N ⇒ k = ⎡log 2 N⎤<br />
Ipotesi implicita<br />
<strong>le</strong> paro<strong>le</strong> di un codice hanno tutte la stessa<br />
lunghezza.<br />
4
Identificare due insiemi:<br />
Insieme del<strong>le</strong> configurazioni ammissibili;<br />
Insieme degli oggetti da rappresentare.<br />
Associare gli e<strong>le</strong>menti dei due insiemi<br />
<strong>Esempio</strong>:<br />
Associare una codifica binaria ai giorni della<br />
settimana<br />
Quanti bit devono avere <strong>le</strong> paro<strong>le</strong> binarie usate per<br />
identificare i giorni della settimana (7 oggetti<br />
diversi)?<br />
k = ⎡log 2 7⎤ = 3<br />
111 010<br />
110 011 001<br />
101 100 000<br />
Insieme degli oggetti<br />
da codificare<br />
Insieme del<strong>le</strong><br />
configurazioni ammissibili<br />
VEN<br />
LUN MAR<br />
GIO<br />
SAB DOM<br />
MER<br />
5
111 010<br />
110 011 001<br />
101 100 000<br />
VEN<br />
bit rappresenta 2 stati: 0 oppure 1.<br />
Codice<br />
LUN MAR<br />
GIO<br />
SAB DOM<br />
Byte rappresenta 8 bit ⇒ 2 8 = 256 stati<br />
KiloByte [KB] = 2 10 Byte = 1024 Byte ≈ 10 3 Byte<br />
MER<br />
MegaByte [MB] = 2 20 Byte = 1048576 Byte ≈ 10 6 Byte<br />
GigaByte [GB] = 2 30 Byte ≈ 10 9 Byte<br />
TeraByte [TB] = 2 40 Byte ≈ 10 12 Byte<br />
…<br />
6
Quanti sono gli oggetti da rappresentare?<br />
26 <strong>le</strong>ttere maiusco<strong>le</strong><br />
26 <strong>le</strong>ttere minusco<strong>le</strong><br />
10 cifre<br />
Circa 30 simboli d’interpunzione (, ; …)<br />
Circa 30 caratteri di controllo (EOF, CR, …)<br />
Tota<strong>le</strong> circa 120 oggetti comp<strong>le</strong>ssivi<br />
⇒ k = ⎡log 2 120⎤ = 7.<br />
Codice ASCII (American Standard Code for<br />
Information Interchange) utilizza 7 bit<br />
⇒ può rappresentare 2 7 = 128 caratteri detti<br />
caratteri ASCII Standard.<br />
Codice ASCII esteso utilizza 8 bit (1 Byte)<br />
⇒ può rappresentare 2 8 = 256 caratteri detti<br />
caratteri ASCII estesi.<br />
Ta<strong>le</strong> codice comprende i caratteri ASCII standard e alcuni<br />
caratteri semigrafici (cornici, <strong>le</strong>ttere nazionali, simboli<br />
matematici, ecc.)<br />
Codice UNICODE utilizza 16 bit (2 Byte)<br />
Uti<strong>le</strong> nel caso di alfabeti particolarmente comp<strong>le</strong>ssi qua<strong>le</strong> quello<br />
cinese<br />
7
Con n bit codifichiamo 2 n <strong>numeri</strong>: da 0 a 2 n -1<br />
Con 1 Byte (cioè una sequenza di 8 bit):<br />
00000000 bin = 0 dec<br />
00001000 bin = 1 × 2 3 = 8 dec<br />
00101011 bin = 1 × 2 5 + 1 × 2 3 + 1 × 2 1 + 1 × 2 0 = 43 dec<br />
11111111 bin = Σ n = 1,2,3,4,5,6,7,8 1 × 2 n -1 = 255 dec<br />
Conversione bin/dec e dec/bin<br />
bin/dec - Σ i 2 i : 11101 bin = (2 4 +2 3 +2 2 +2 0 )= 29 dec<br />
dec/bin - metodo dei resti<br />
Si calcolano i resti del<strong>le</strong> divisioni per due<br />
In pratica basta:<br />
1. Decidere se il numero sia pari (resto 0)<br />
oppure dispari (resto 1), e annotare il resto<br />
2. Dimezzare il numero (trascurando il resto)<br />
3. Ripartire dal punto 1. fino a ottenere 1<br />
oppure 0 come risultato della divisione<br />
si ottiene 1: fine<br />
19 : 2 → 1<br />
9 : 2 → 1<br />
4 : 2 → 0<br />
2 : 2 → 0<br />
1 : 2 → 1<br />
19 dec =10011 bin<br />
8
29 : 2 = 14 (1)<br />
14 : 2 = 7 (0)<br />
7 : 2 = 3 (1)<br />
3 : 2 = 1 (1)<br />
1 : 2 = 0 (1)<br />
29 dec = 11101 bin<br />
Del resto 76 = 19x4 = 1001100<br />
Per raddoppiare, in base due, si<br />
aggiunge uno zero in coda, così come si<br />
fa in base dieci per decuplicare<br />
76 : 2 = 38 (0)<br />
38 : 2 = 19 (0)<br />
19 : 2 = 9 (1)<br />
9 : 2 = 4 (1)<br />
4 : 2 = 2 (0)<br />
2 : 2 = 1 (0)<br />
1 : 2 = 0 (1)<br />
76 dec = 1001100 bin<br />
N.B. Il metodo funziona<br />
con tutte <strong>le</strong> basi!<br />
29 10 =45 6 =23 13 =10 29<br />
In binario si definisce una notazione abbreviata, sulla falsariga<br />
del sistema metrico-decima<strong>le</strong>:<br />
K = 2 10 = 1.024 ≈ 10 3 (Kilo)<br />
M = 2 20 = 1.048.576 ≈ 10 6 (Mega)<br />
G = 2 30 = 1.073.741.824 ≈ 10 9 (Giga)<br />
T = 2 40 = 1.099.511.627.776 ≈ 10 12 (Tera)<br />
È curioso (benché non sia casua<strong>le</strong>) come K, M, G e T in base 2<br />
abbiano valori molto prossimi ai corrispondenti simboli del<br />
sistema metrico decima<strong>le</strong>,<br />
tipico del<strong>le</strong> scienze fisiche e dell’ingegneria<br />
L’errore risulta < 10 %<br />
Casi Notevoli<br />
2 32 = 2 2+30 = 4 G – importante per sistemi a 32 bit<br />
2 16 = 64KB – importante per ragioni storiche<br />
9
Aumento dei bit<br />
premettendo in modo progressivo un bit 0 a sinistra, il valore<br />
del numero non muta<br />
4 dec = 100 bin = 0100 bin = 00100 bin = … 000000000100 bin<br />
5 dec = 101 bin = 0101 bin = 00101 bin = … 000000000101 bin<br />
Riduzione dei bit<br />
cancellando in modo progressivo un bit 0 a sinistra, il valore<br />
del numero non muta, ma bisogna arrestarsi quando si trova<br />
un bit 1!<br />
7 dec = 00111 bin = 0111 bin = 111 bin STOP !<br />
2 dec = 00010 bin = 0010 bin = 010 bin = 10 bin STOP !<br />
Il primo bit a sinistra rappresenta il segno del numero (bit di<br />
segno), i bit rimanenti rappresentano il valore<br />
0 per il segno positivo, 1 per il segno negativo<br />
Il bit di segno è applicato al numero rappresentato, ma non fa<br />
propriamente parte del numero<br />
il bit di segno non ha significato <strong>numeri</strong>co<br />
Inefficiente: due codifiche per lo 0<br />
Comp<strong>le</strong>ssità di imp<strong>le</strong>mentazione<br />
Esempi con n = 9 (8 bit + un bit per il segno)<br />
000000000 m&s = + 0 =<br />
000001000 m&s = + 1 × 2 3 = 8 dec<br />
100001000 m&s = - 1 × 2 3 = -8 dec<br />
… e così via …<br />
10
Numeri <strong>interi</strong> in comp<strong>le</strong>mento a 2: il C 2 è un sistema<br />
binario, ma il primo bit (quello a sinistra, il più<br />
significativo) ha peso negativo, mentre tutti gli altri<br />
bit hanno peso positivo<br />
La sequenza di bit:<br />
b n b n-1 … b 1<br />
rappresenta in C 2 il valore:<br />
b n ×(-2 n-1 )+ b n-1 ×2 n-2 + … + b 1 ×20<br />
Il bit più a sinistra è ancora chiamato bit di segno<br />
000 C2 = –0×2 2 + 0×2 1 + 0×2 0 = 0 dec<br />
001 C2 = –0×2 2 + 0×2 1 + 1×2 0 = 1 dec<br />
010 C2 = –0×2 2 + 1×2 1 + 0×2 0 = 2 dec<br />
011 C2 = –0×2 2 + 1×2 1 + 1×2 0 = 2+1 = 3 dec<br />
100 C2 = –1×2 2 + 0×2 1 + 0×2 0 = -4 dec<br />
101 C2 = –1×2 2 + 0×2 1 + 1×2 0 = -4+1 = -3 dec<br />
110 C2 = –1×2 2 + 1×2 1 + 0×2 0 = -4+2 = -2 dec<br />
111 C2 = –1×2 2 + 1×2 1 + 1×2 0 = -4+2+1 = -1 dec<br />
N.B.: in base al bit di segno lo zero è considerato positivo<br />
11
Se usiamo 1 Byte: da –128 a 127<br />
dec. 127 m&s 01111111 C 2 01111111<br />
126 01111110 01111110<br />
… … …<br />
2 00000010 00000010<br />
1 00000001 00000001<br />
+0 00000000 00000000<br />
-0 10000000 -<br />
-1 10000001 11111111<br />
-2 10000010 11111110<br />
… … …<br />
-126 11111110 10000010<br />
-127 11111111 10000001<br />
-128 - 10000000<br />
L’inverso additivo (o opposto) di un numero in C 2 si ottiene:<br />
Invertendo (negando) ogni bit del numero<br />
Sommando 1 alla posizione meno significativa<br />
<strong>Esempio</strong>:<br />
01011C2 = 1×23 +1×21 +1×20 = 8+2+1 = 11dec 10100 + 1 = 10101C2 = -1×24 +1×22 +1×20 = -16+4+1 = -11dec Si provi a invertire 11011C2 = -5dec Si verifichi che con due applicazioni dell’algoritmo si riottiene il<br />
numero inizia<strong>le</strong> [ –(–A) = A ] e che lo zero in C 2 è (correttamente)<br />
opposto di se stesso [ –0 = 0 ]<br />
12
Se D dec ≥ 0:<br />
Converti D dec in binario natura<strong>le</strong><br />
Premetti il bit 0 alla sequenza di bit ottenuta<br />
<strong>Esempio</strong>: 154 dec ⇒ 10011010 bin ⇒ 010011010 C2<br />
Se D dec < 0:<br />
Trascura il segno e converti D dec in binario natura<strong>le</strong><br />
Premetti il bit 0 alla sequenza di bit ottenuta<br />
Calcola l’opposto del numero così ottenuto, secondo la<br />
procedura di inversione in C 2<br />
<strong>Esempio</strong>: -154 dec ⇒ 154 dec ⇒ 10011010 bin ⇒<br />
⇒ 010011010 bin ⇒ 101100101 + 1 ⇒ 101100110 C2<br />
Occorrono 9 bit sia per 154 dec che per -154 dec<br />
Il segno è incorporato nel numero rappresentato in C 2 , non è<br />
semplicemente applicato (come in m&s)<br />
Il bit più significativo rivela il segno: 0 per numero positivo, 1<br />
per numero negativo (il numero zero è considerato positivo),<br />
ma…<br />
Se il numero e’ negativo, NON si può distaccare il bit più<br />
significativo e dire che i bit rimanenti rappresentano il valore<br />
assoluto del numero<br />
13
Binario natura<strong>le</strong> a n ≥ 1 bit: [0, 2 n )<br />
Modulo e segno a n ≥ 2 bit: (-2 n-1 , 2 n-1 )<br />
C 2 a n ≥ 2 bit: [-2 n-1 , 2 n-1 )<br />
In modulo e segno, il numero zero ha due<br />
rappresentazioni equiva<strong>le</strong>nti (00..0, 10..0)<br />
L’intervallo del C 2 è asimmetrico<br />
⎡log 2 valore⎤ = # di bit per rappresentare il<br />
valore (in binario natura<strong>le</strong>).<br />
<strong>Esempio</strong>: ⎡log 2 74 dec ⎤ = ⎡6,2…⎤ = 7 bit<br />
In genera<strong>le</strong>: ⎡log B valore⎤ = # di cifre per<br />
rappresentare il valore in base B.<br />
<strong>Esempio</strong>: ⎡log 10 74 dec ⎤ = ⎡1,8…⎤ = 2 cifre<br />
E per il C 2 ?<br />
14
Riporto<br />
“perduto”<br />
Algoritmo di “addizione a propagazione dei riporti”<br />
È l’algoritmo decima<strong>le</strong> e<strong>le</strong>mentare, adattato alla base 2<br />
addizione natura<strong>le</strong> (a 8 bit)<br />
overflow<br />
overflow (o trabocco)<br />
1<br />
risultato errato!<br />
addizione natura<strong>le</strong> con overflow<br />
15
Si ha overflow quando il risultato corretto<br />
dell’addizione eccede il potere di rappresentazione<br />
dei bit a disposizione<br />
8 bit nell’esempio precedente<br />
Nell’addizione tra <strong>numeri</strong> binari naturali si ha<br />
overflow ogni volta che si genera un riporto<br />
addizionando i bit della colonna più significativa<br />
(riporto “perduto”)<br />
addizione algebrica (a 8 bit)<br />
L’algoritmo è identico a quello natura<strong>le</strong><br />
(come se il bit di segno non fosse negativo)<br />
16
nessun<br />
riporto<br />
“perduto”<br />
Overflow:<br />
risultato negativo!<br />
ancora overflow<br />
risultato errato!<br />
addizione algebrica con overflow<br />
Si ha overflow quando il risultato corretto<br />
dell’addizione eccede il potere di rappresentazione dei<br />
bit a disposizione<br />
La definizione di overflow non cambia<br />
Si può avere overflow senza “riporto perduto”<br />
Capita quando da due addendi positivi otteniamo un risultato<br />
negativo, come nell’esempio precedente<br />
Si può avere un “riporto perduto” senza overflow<br />
Può essere un innocuo effetto collatera<strong>le</strong><br />
Capita quando due addendi discordi generano un risultato<br />
positivo (si provi a sommare +12 e -7)<br />
17
Se gli addendi sono tra loro discordi (di segno<br />
diverso) non si verifica mai<br />
Se gli addendi sono tra loro concordi, si verifica se e<br />
solo se il risultato è discorde<br />
addendi positivi ma risultato negativo<br />
addendi negativi ma risultato positivo<br />
Otta<strong>le</strong> o in base otto (oct):<br />
Si usano solo <strong>le</strong> cifre 0-7<br />
534 oct = 5 oct ×8 dec 2 + 3oct ×8 dec 1 + 4oct ×8 dec 0 = 348 dec<br />
Esadecima<strong>le</strong> o in base sedici (hex):<br />
Si usano <strong>le</strong> cifre 0-9 e <strong>le</strong> <strong>le</strong>ttere A-F per i valori 10-15<br />
B7F hex = B hex ×16 dec 2 + 7hex ×16 dec 1 + Fhex ×16 dec 0 =<br />
= 11 dec ×16 dec 2 + 7dec ×16 dec 1 + 15dec ×16 dec 0 = 2943 dec<br />
Entrambe queste basi sono facili da convertire in<br />
binario, e viceversa<br />
18
o Converti: 010011110101011011 bin =<br />
0001 bin 0011 bin 1101 bin 0101 bin 1011 bin =<br />
= 1 hex 3 hex D hex 5 hex B hex =<br />
= 13D5B hex<br />
o Converti: A7B40C hex<br />
A hex 7 hex B hex 4 hex 0 hex C hex =<br />
= 1010 bin 0111 bin 1011 bin 0100 bin 0000 bin 1100 bin =<br />
= 101001111011010000001100 bin<br />
La codifica esadecima<strong>le</strong> è uti<strong>le</strong> per rappresentare<br />
sinteticamente i valori binari<br />
0,1011 bin (in binario)<br />
0,1011 bin = 1×2 -1 + 0×2 -2 + 1×2 -3 + 1×2 -4 = 1/2 + 1/8 + 1/16 =<br />
= 0,5 + 0,125 + 0,0625 = 0,6875 dec<br />
Si può rappresentare un numero frazionario in virgola fissa (o<br />
fixed point) nel modo seguente:<br />
19,6875 dec = 10011,1011 virgola fissa<br />
poiché si ha:<br />
19 dec = 10011 bin e 0,6875 dec = 0,1011 bin<br />
proporzione fissa:<br />
5 bit per la parte intera, 4 bit per quella frazionaria<br />
19
La sequenza di bit rappresentante un numero<br />
frazionario consta di due parti di lunghezza prefissata<br />
Il numero di bit a sinistra e a destra della virgola è stabilito a<br />
priori, anche se alcuni bit restassero nulli<br />
È un sistema di rappresentazione semplice, ma poco<br />
f<strong>le</strong>ssibi<strong>le</strong>, e può condurre a sprechi di bit<br />
Per rappresentare in virgola fissa <strong>numeri</strong> molto grandi<br />
(oppure molto precisi) occorrono molti bit<br />
La rappresentazione in virgola mobi<strong>le</strong> (o floating point) è usata<br />
spesso in base 10<br />
(si chiama allora notazione scientifica):<br />
0,137 × 108 notazione scientifica per intendere 13.700.000dec La rappresentazione binaria si basa sulla relazione<br />
R virgola mobi<strong>le</strong> = M × 2E Segno<br />
Esponente<br />
Mantissa<br />
La mantissa e’ sempre 1.X, per cui si salva solo X.<br />
20
L’algebra di Boo<strong>le</strong> (inventata da G. Boo<strong>le</strong>,<br />
britannico, seconda metà ’800), o algebra della<br />
logica, si basa su operazioni logiche<br />
Le operazioni logiche sono applicabili a operandi<br />
logici, cioè a operandi in grado di assumere solo i<br />
valori vero e falso<br />
Si può rappresentare vero con il bit 1 e falso con il<br />
bit 0 (convenzione di logica positiva)<br />
22
Operatori logici binari (con 2 operandi logici)<br />
Operatore OR, o somma logica<br />
Operatore AND, o prodotto logico<br />
Operatore logico unario (con 1 operando)<br />
Operatore NOT, o negazione, o inversione<br />
Poiché gli operandi logici ammettono due soli<br />
valori, si può definire compiutamente ogni<br />
operatore logico tramite una tabella di<br />
associazione operandi-risultato<br />
A B A or B<br />
0 0 0<br />
0 1 1<br />
1 0 1<br />
1 1 1<br />
(somma logica)<br />
A B A and B<br />
0 0 0<br />
0 1 0<br />
1 0 0<br />
1 1 1<br />
(prodotto logico)<br />
Le tabel<strong>le</strong> e<strong>le</strong>ncano tutte <strong>le</strong> possibili<br />
combinazioni in ingresso e il risultato<br />
associato a ciascuna combinazione<br />
A not A<br />
0 1<br />
1 0<br />
(negazione)<br />
23
Come <strong>le</strong> espressioni algebriche, costruite con:<br />
Variabili logiche (<strong>le</strong>tterali): p. es. A, B, C = 0 oppure 1<br />
Operatori logici: and, or, not<br />
Esempi:<br />
A or (B and C)<br />
(A and (not B)) or (B and C)<br />
L’operatore “not” precede l’operatore “and”, che a sua volta<br />
precede l’operatore “or”<br />
(A and (not B)) or (B and C) = A and not B or B and C<br />
Per ricordarlo, si pensi OR come “+” (più), AND come “×” (per) e<br />
NOT come “-” (cambia segno)<br />
A B NOT ( ( A OR B) AND ( NOT A ) )<br />
0 0 1<br />
0 1 0<br />
1 0 1<br />
1 1 1<br />
Specificano i valori di verità<br />
per tutti i possibili valori<br />
del<strong>le</strong> variabili<br />
24
A and B or not C<br />
A B C X = A and B Y = not C X or Y<br />
0 0 0 0 and 0 = 0 not 0 = 1 0 or 1 = 1<br />
0 0 1 0 and 0 = 0 not 1 = 0 0 or 0 = 0<br />
0 1 0 0 and 1 = 0 not 0 = 1 0 or 1 = 1<br />
0 1 1 0 and 1 = 0 not 1 = 0 0 or 0 = 0<br />
1 0 0 1 and 0 = 0 not 0 = 1 0 or 1 = 1<br />
1 0 1 1 and 0 = 0 not 1 = 0 0 or 0 = 0<br />
1 1 0 1 and 1 = 1 not 0 = 1 1 or 1 = 1<br />
1 1 1 1 and 1 = 1 not 1 = 0 1 or 0 = 1<br />
A modellare alcune (non tutte) forme di ragionamento<br />
A = è vero che 1 è maggiore di 2 ? (sì o no, qui è no) = 0<br />
B = è vero che 2 più 2 fa 4 ? (sì o no, qui è sì) = 1<br />
A and B = è vero che 1 sia maggiore di 2 e che 2 più 2 faccia 4 ?<br />
Si ha che A and B = 0 and 1 = 0, dunque no<br />
A or B = è vero che 1 sia maggiore di 2 o che 2 più 2 faccia 4 ?<br />
Si ha che A or B = 0 and 1 = 1, dunque sì<br />
OR, AND e NOT vengono anche chiamati connettivi logici, perché<br />
funzionano come <strong>le</strong> congiunzioni coordinanti “o” ed “e”, e come la<br />
negazione “non”, del linguaggio natura<strong>le</strong><br />
Si modellano ragionamenti (o deduzioni) basati solo sull’uso di “o”,<br />
“e” e “non” (non è molto, ma è uti<strong>le</strong>)<br />
25
Due espressioni logiche si dicono equiva<strong>le</strong>nti (e si indica con<br />
⇔) se hanno la medesima tabella di verità. La verifica è<br />
algoritmica. Per esempio:<br />
A B not A and not B ⇔ not (A or B)<br />
0 0 1 and 1 = 1 not 0 = 1<br />
0 1 1 and 0 = 0 not 1 = 0<br />
1 0 0 and 1 = 0 not 1 = 0<br />
1 1 0 and 0 = 0 not 1 = 0<br />
• Espressioni logiche equiva<strong>le</strong>nti modellano gli stessi<br />
stati di verità a fronte del<strong>le</strong> medesime variabili<br />
L’algebra di Boo<strong>le</strong> gode di svariate proprietà,<br />
formulabili sotto specie di identità<br />
(cioè formulabili come equiva<strong>le</strong>nze tra espressioni logiche,<br />
valide per qualunque combinazione di valori del<strong>le</strong> variabili)<br />
<strong>Esempio</strong> ce<strong>le</strong>bre: <strong>le</strong> “Leggi di De Morgan”<br />
not (A and B) = not A or not B (1 a <strong>le</strong>gge)<br />
not (A or B) = not A and not B (2 a <strong>le</strong>gge)<br />
26
Alcune proprietà somigliano a quel<strong>le</strong> dell’algebra<br />
<strong>numeri</strong>ca tradiziona<strong>le</strong>:<br />
Proprietà associativa: A or (B or C) = (A or B) or C (idem per AND)<br />
Proprietà commutativa: A or B = B or A (idem per AND)<br />
Proprietà distributiva di AND rispetto a OR:<br />
A and (B or C) = A and B or A and C<br />
… e altre ancora<br />
Ma parecchie altre sono alquanto insolite…<br />
Proprietà distributiva di OR rispetto a AND:<br />
A or B and C = (A or B) and (A or C)<br />
Proprietà di assorbimento (A assorbe B):<br />
A or A and B = A<br />
Legge dell’e<strong>le</strong>mento 1: not A or A = 1<br />
… e altre ancora<br />
27
Il calcolatore esegue programmi scritti in un<br />
opportuno linguaggio: il linguaggio macchina<br />
Ta<strong>le</strong> linguaggio differisce nei suoi dettagli da<br />
calcolatore a calcolatore<br />
Da processore a processore<br />
Un programma scritto in linguaggio macchina è formato da una<br />
sequenza di istruzioni appartenenti al set di istruzioni del<br />
particolare processore<br />
Ogni istruzione è formata da:<br />
Un codice operativo<br />
00100 … 1000 100010010010 … 11<br />
Zero o più operandi<br />
codice operativo operando(i)<br />
Tanto il codice operativo quanto gli operandi sono<br />
rappresentati nella memoria del calcolatore sotto forma di<br />
<strong>numeri</strong> binari<br />
Data la difficoltà per l’uomo di interpretare <strong>numeri</strong> binari si<br />
usa il linguaggio assembly al posto del linguaggio macchina<br />
28
La programmazione in linguaggio macchina è troppo<br />
comp<strong>le</strong>ssa e noiosa per i programmatori<br />
Al posto del<strong>le</strong> sequenze di <strong>numeri</strong>, è più comodo<br />
usare del<strong>le</strong> abbreviazioni simili all’ing<strong>le</strong>se per<br />
rappresentare <strong>le</strong> operazioni e<strong>le</strong>mentari: Nasce il<br />
linguaggio Assembly<br />
È necessario un programma (assemb<strong>le</strong>r) che traduca<br />
in linguaggio macchina i programmi scritti in<br />
linguaggio assembly<br />
Un programma consiste di 2<br />
parti<br />
La parte istruzioni contenente<br />
il codice del programma<br />
La parte dati costituita dal<strong>le</strong><br />
cel<strong>le</strong> di memoria destinate a<br />
contenere i dati sui quali il<br />
programma opera<br />
Il processore esegue un<br />
programma dalla prima<br />
istruzione fino all’istruzione<br />
halt<br />
0<br />
1<br />
2<br />
3<br />
4<br />
5<br />
LOAD 4, R1<br />
LOAD 5, R2<br />
SUB R1, R2<br />
STORE R1, 7<br />
50<br />
40<br />
istruzio<br />
ni<br />
dati<br />
29
La programmazione in linguaggio macchina è<br />
improponibi<strong>le</strong> per programmi di una certa<br />
comp<strong>le</strong>ssità...<br />
... e l’assembly oltre un certo limite non aiuta<br />
I linguaggi di alto livello facilitano la<br />
programmazione dei calcolatori<br />
“Alto livello” = “Vicino al programmatore”<br />
Ovviamente è necessario un programma<br />
(compilatore) che converta il programma scritto<br />
nel linguaggio di alto livello<br />
in linguaggio macchina<br />
Editazione - Genera il programma sorgente<br />
Consiste nella scrittura del codice (testo del programma) in un fi<strong>le</strong><br />
Si esegue tramite un programma chiamato editor o Ambiente di sviluppo<br />
Compilazione - Genera il programma oggetto<br />
Il codice sorgente viene passato al compilatore che si occuperà di tradurre il programma<br />
nel codice in linguaggio macchina<br />
Linking (col<strong>le</strong>gamento) - Genera il programma eseguibi<strong>le</strong><br />
I programmi scritti in linguaggio ad alto livello, contengono dei riferimenti a funzioni<br />
definite altrove (es. Librerie e OS)<br />
Il codice oggetto prodotto dal compilatore conterrà dei “buchi” (riferimenti al<strong>le</strong> funzioni<br />
di libreria)<br />
Il linker si occupa di col<strong>le</strong>gare il codice oggetto con quello del<strong>le</strong> funzioni mancanti<br />
Caricamento<br />
Prima che possa essere eseguito, un programma dovrà essere caricato in memoria<br />
Il programma loader (parte del sistema operativo) si occupa di questa operazione<br />
Esecuzione<br />
Il computer esegue il programma, una istruzione per volta<br />
30
Il calcolatore “capisce” solo il linguaggio<br />
macchina<br />
I programmi scritti in linguaggi di alto livello<br />
devono essere tradotti in linguaggio macchina<br />
prima di essere eseguiti<br />
Di ciò si occupa il compilatore<br />
In alternativa alcuni linguaggi di alto livello<br />
hanno associato un interprete<br />
Si tratta di un programma capace di “capire” quel<br />
particolare linguaggio e di eseguirne i programmi<br />
Un’istruzione per volta<br />
31