scarica le dispense - Istituto Angioy Carbonia, Corso di Informatica

ISTITUTO TECNICO E LICEO SCIENTIFICO TECNOLOGICO “ANGIOY”
LA RAPPRESENTAZIONE DELLE INFORMAZIONI
Prof. G. Ciaschetti
DATI E INFORMAZIONI
Sappiamo che il computer è una macchina stupida, capace di eseguire calcoli in modo velocissimo,
ma non capace di pensare. Quando memorizziamo nel computer un qualsiasi dato, sia esso un
numero, una parola, un‟immagine, un suono, non è possibile fare in modo che a questo dato il
computer associ anche un significato: per fare questo, occorre un cervello pensante, come quello
dell‟uomo, molto più intelligente di un computer.
Facciamo qualche esempio: se diciamo che lo sconto su un paio di scarpe da tennis è del 20 per
cento, sappiamo che il numero 20 rappresenta uno sconto, ma nel computer potrò inserire solo il
numero 20, in quanto non esso non è capace di associare al numero il fatto che rappresenta uo
sconto. Un altro esempio: se l‟età di una persona è 18 anni, il computer può memorizzare 18, ma
non il fatto che questa sia un‟età. Funziona anche per le immagini, i suoni e i video: un‟immagine
nel computer è solo un‟insieme di bit, messi in modo da dare un colore a ogni pixel dello schermo,
ma il computer non sa assolutamente se l‟immagine che risulta riguarda una scena sportiva o una
bella donna o qualsiasi altra cosa: l’uomo associa un significato ai dati, facendoli così diventare
informazioni! Il computer, invece, sa trattare solo dati “grezzi” privi di significato, tutti
rappresentati usando il linguaggio binario.
Il linguaggio binario, come ogni linguaggio, è costruito su un alfabeto. L‟alfabeto binario, come è
noto, è formato dai soli simboli 0 e 1 (a differenza dell‟alfabeto italiano che ha le 21 lettere A, B,
…, Z o quello inglese che ha le 26 lettere A, B, …, Y, Z). Per costruire il linguaggio, a partire
dall‟alfabeto, si usano parole. Mentre nei linguaggi naturali (quelli dell‟uomo, ad esempio, italiano,
inglese, russo, ecc.) le parole possono avere dimensioni qualsiasi (pippo è una parola di 5 simboli,
ciao di 4, ecc.), nel computer le parole hanno dimensione fissa, che dipende dal particolare
computer. Solitamente, le parole possono essere di 1 byte, 2 byte, 4 byte oppure 8 byte. (un byte è
una sequenza di 8 bit). Quindi, ad esempio, se un computer ha parole di 4 byte, esso userà sempre e
solo parole formate con 32 simboli 0 o 1, cioè 32 bit.
Quante parole è possibile formare con tutti i simboli di un alfabeto? Vale la seguente regola:
con un alfabeto di n simboli, e parole formate da p simboli, si possono costruire
np diverse parole.
Esempio: se l’alfabeto è quello del sistema numerico decimale {0,1,…, 9} e abbiamo parole di 4 simboli,
possiamo costruire tutte le 104 = 10000 parole 0000, 0001, 0002, 0003, …, 9999.
Esempio: se l’alfabeto è quello binario {0,1} e abbiamo parole di 3 bit, possiamo costruire le 23 = 8 parole 000,
001, 010, 011, …, 111 (cioè tutti i numeri da 0 a 7).
Esempio: se l’alfabeto è quello italiano {A,B,C,…,Z} e abbiamo parole di 2 lettere, possiamo costruire tutte le
212 = 441 parole AA, AB, AC, …,AZ, BA, BB, …, BZ, …, ZZ.
Prima di iniziare la nostra trattazione su come sono rappresentati tutti i dati (e quindi le
informazioni, per noi uomini) all‟interno del computer, un po‟ di definizioni:
1 byte = 8 bit
1 Kbyte (chilo) = 210 byte = 1024 byte
1 Mbyte (mega) = 210 Kbyte = 1024 Kbyte (= 220 byte)
1 Gbyte (giga) = 210 Mbyte = 1024 Mbyte (= 230 byte)
1 Tbyte (tera) = 210 Gbyte = 1024 Gbyte (= 240 byte)
TIPI DI DATI
Classificando i dati secondo il loro tipo, distinguiamo innanzitutto dati numerici e dati
alfanumerici. I primi sono i numeri, così come li conosciamo dalla matematica, mentre gli altri
comprendono le lettere e tutti i caratteri speciali (la virgola, il punto e virgola, le parentesi tonde, lo
spazio bianco, ecc.).
Tra i numeri, possiamo distinguere i numeri interi (che non hanno una parte decimale) e i numeri
reali (che invece hanno una parte decimale). A loro volta, i numeri interi possono essere suddivisi
in interi senza segno (solo interi positivi) e interi con segno (positivi e negativi).
I numeri reali possono essere in singola o in doppia precisione, intendendo con precisione il grado
di approssimazione che è possibile effettuare per i numeri irrazionali (che non possono essere
memorizzati completamente in quanto hanno infinite cifre decimali).
I dati alfanumerici possono essere singoli caratteri (come le lettera „A‟, „B‟, o i segni di
punteggiatura, o le parentesi, o ogni altro simbolo che possiamo digitare sulla tastiera) o sequenze
di caratteri dette stringhe (sono un po‟ come le nostre parole, ad esempio “pippo”, “ciao mondo”,
ecc.).
Impareremo, tra poco, come ognuno di questi tipi di dato è memorizzato nel computer, e quali sono
i tipi predefiniti messi a disposizione dal linguaggio C, che sono riassunti nella seguente figura.
RAPPRESENTAZIONE DEI NUMERI INTERI SENZA SEGNO
Sono i numeri binari con cui abbiamo lavorato finora. Supponiamo di avere parole di 1 byte e
consideriamo per il momento solo numeri interi positivi. I numeri che possiamo rappresentare con
l‟alfabeto {0,1} su 8 bit sono tutti i numeri da 0 a 28-1 = 255. Se invece abbiamo parole di 2 byte, i
numeri che possiamo rappresentare sono tutti quelli da 0 a 216-1 = 65535. In generale,
con n bit si possono rappresentare tutti i numeri interi positivi da 0 a 2n -1.
Linguaggio C: possono essere definiti i seguenti tipi di dato interi senza segno (positivi)
Tipo di dato
unsigned short int
unsigned int
unsigned long int
numero di byte
2 byte
1 parola (2 o 4 byte, il
numero dipende dal
particolare computer)
4 byte
Intervallo valori ammessi
da 0 a 65535
da 0 a 4294967295
RAPPRESENTAZIONE DEI NUMERI INTERI CON SEGNO
L‟insieme dei numeri interi comprende, oltre agli interi positivi, anche gli interi negativi. Come
questi vengono rappresentati? Supponiamo sempre di avere parole di 2 byte. Dei 16 bit a
disposizione, il primo bit a sinistra viene usato per il segno: 0 se il numero è positivo, 1 se il
numero è negativo. In questo caso, per i numeri interi positivi rimangono 15 bit a disposizione,
quindi, si ha la possibilità di rappresentare tutti i numeri da 0 a 32767. Se invece abbiamo parole di
1 byte, tolto un bit per il segno, restano 7 bit a disposizione con cui rappresentiamo tutti i numeri
positivi da 0 a 27 – 1 = 127. In generale, se usiamo un bit per rappresentare il segno in un numero di
n bit, ne restano a disposizione n-1 per il valore assoluto, e quindi potremo rappresentare i numeri
positivi fino a 2n-1 -1.
I numeri negativi, invece, sono rappresentati non in valore assoluto, ma in complemento a 2: il
numero –N è rappresentato come il complemento a 2 del numero N. Ma cos‟è, esattamente, il
complemento di un numero?
data una base b, e un numero N in base b di n cifre, si definisce complemento di N il numero
N(b) = bn - N
Esempio: se b=10, e N = 982, risulta n = 3 e abbiamo 982(10) = 103 – 982 = 18
Esempio: se b=2, e N = 001, risulta n = 3 e abbiamo 001(2) = 23 – 1 = 111
Esempio: se b=10, e N = 24, risulta n = 2 e abbiamo 24(10) = 102 – 24 = 78
Dagli esempi, si può osservare che il complemento di un numero è quanto manca al numero per
arrivare alla prossima potenza della base. Nel primo esempio, quanto manca a 982 per arrivare a
1000, nel secondo esempio quanto manca a 1 per arrivare a 8 in binario. Nel terzo esempio, quanto
manca a 24 per arrivare a 100.
Per trovare il complemento di un numero binario, anche detto complemento a 2, possiamo seguire
una regola pratica molto semplice (di fatto, il computer fa così):
si prende il numero in binario, si sostituisce ogni 0 con 1, e ogni 1 con 0, e poi si somma 1.
Per far ciò, tuttavia, è necessario fissare il numero di bit della parola con cui sarà rappresentato il
numero, altrimenti non funziona. Negli esempi che seguono, prendiamo parole di 1 byte, ma
potrebbero tranquillamente essere di 2 byte, 4 byte o quanti vogliamo.
Esempio: dato il numero
01010011
si scambiano le cifre
si somma 1
complemento a 2
10101100 +
1=
10101101
Esempio: dato il numero
01011110
si scambiano le cifre
si somma 1
complemento a 2
10100001 +
1=
10100010
Torniamo ai numeri negativi: abbiamo detto che sono rappresentati in complemento a 2. Ma come?
Semplice, si scrive il numero come positivo, con tutti i bit a disposizione nella parola, e si fa il suo
complemento applicando la regola appena vista. Supponendo ancora di avere parole di 1 byte,
Esempio: rappresentazione di -5
rappresentiamo il 5
facciamo il suo complemento
00000101
11111011
Esempio: rappresentazione di -121
rappresentiamo il 121
facciamo il suo complemento
01111001
10000111
Possiamo verificare che il numero negativo così rappresentato è proprio l‟opposto del suo valore
assoluto. Infatti, se fissiamo il numero di bit (ad esempio 8), e ignoriamo eventuali riporti su cifre
eccedenti a sinistra, possiamo verificare quanto detto
Esempio: 5 + (-5) = 0
rappresentazione di 5
rappresentazione di -5
somma
00000101
11111011
100000000 (sarebbe infatti 28 se potessimo prendere il nono bit)
Facciamo anche un esempio supponendo di avere a disposizione parole di 2 byte.
Esempio: rappresentazione di -65
rappresentiamo il 65
facciamo il suo complemento
0000000001000001
1111111110111111
Vediamo allora quali numeri negativi possiamo rappresentare. Nell‟ipotesi di avere due byte a
disposizione per le nostre parole, iniziamo col fare il complemento a 2 dei numeri 1, 2, ….
1
2
3
4
…
0000000000000001
0000000000000010
0000000000000011
0000000000000100
-1
-2
-3
-4
1111111111111111
1111111111111110
1111111111111101
1111111111111100
Come si può osservare, i numeri positivi iniziano con 0, quelli negativi con 1. Inoltre, mentre i
numeri positivi crescono, quelli negativi decrescono. Arriviamo fino ai più grandi positivi che
possiamo rappresentare su due byte.
32765
32766
32767
0111111111111101
0111111111111110
0111111111111111
-32765
-32766
-32767
1000000000000011
1000000000000010
1000000000000001
Possiamo decrescere ancora con i numeri negativi (mentre per quelli positivi non possiamo più
crescere), quindi possiamo rappresentare anche il -32768 con 1000000000000000.
In definitiva, con 2 byte a disposizione, possiamo rappresentare tutti i numeri interi da -32768 a
32767. Se avessimo invece parole di un solo byte, potremmo rappresentare tutti gli interi da -128 a
127. In generale, vale la seguente regola:
con n bit si possono rappresentare tutti i numeri interi con segno da -2n-1 a 2n-1 -1.
Linguaggio C: possono essere definiti i seguenti tipi di dato interi con segno:
Tipo di dato
short int
int
numero di byte
2 byte
1 parola, di 2 o 4 byte (il numero
dipende dal computer)
4 byte
long int
intervallo valori ammessi
Da -32768 a 32767
…
Da -2147483648 a 2147483647
Se in un calcolo succede di arrivare a cifre maggiori o minori di quelle che si possono
rappresentare, si dice che c‟è un errore di overflow. Solitamente, in questi casi il programma in
esecuzione si blocca, oppure può succedere che vengono semplicemente ignorate le cifre più
significative, cioè quelle più a sinistra, causando una perdita di informazione.
RAPPRESENTAZIONE DEI NUMERI REALI
Iniziamo col dire che non è possibile rappresentare nel computer reali irrazionali come √2 o .
Questo perché essi hanno infinite cifre decimali, e servirebbe una memoria infinita per contenerli.
Di conseguenza, possono essere rappresentati solo numeri razionali, e nemmeno tutti, solo quelli
senza troppe cifre decimali.
La rappresentazione che noi umani siamo abituati ad usare è quella in virgola fissa, che prevede di
elencare a sinistra della virgola la parte intera, e a destra della virgola la parte decimale.
Esempi:
1.5
0.000123
12.01
Il computer invece utilizza una rappresentazione in virgola mobile, o anche detta notazione
scientifica. In questa, si distinguono una mantissa e un esponente, e si usa la lettera E per separare
le due cose. Il significato del numero è il seguente:
mantissaEesponente = mantissa * 10 esponente.
Esempi:
numero in virgola mobile
numero rappresentato
numero in virgola fissa
3E-4
3*10-4
0.0003
-12E5
-12*105
-120000
1.4E2
1.4*102
1400
Un numero in virgola mobile può sempre essere scritto in modo che la mantissa abbia un valore
assoluto minore di 1, e la prima cifra decimale maggiore di zero. In questo caso, si parla di
notazione in virgola mobile normalizzata, e l‟esponente prende il nome di caratteristica (ma
molto spesso capita che si evita questa precisazione parlando semplicemente di virgola mobile,
mantissa ed esponente).
Esempi:
virgola mobile normalizzata
3E-4
0.3E-3
12E5
0.12E7
1.4E2
0.14E3
In genere, i reali sono rappresentati su più parole, poiché per essi è richiesta una precisione
maggiore che per gli interi. Avendo a disposizione 4 byte, ad esempio, la ripartizione dei bit è come
segue:
 Un bit per il segno (0 se positivo, 1 se negativo)
 8 bit per la caratteristica
(aumentata di 127, negativa se <127, positiva se >127)
 23 bit per la mantissa (lo 0 e la virgola non sono rappresentati)
In generale, la rappresentazione avviene secondo la seguente formula,
(-1)s × m × 2(e
- 127)
dove abbiamo indicato il bit di segno con s, la mantissa con m e l‟esponente o caratteristica con e.
Se si hanno a disposizione 8 byte, invece, il numero di bit per la mantissa e la caratteristica risulta
raddoppiato. Più precisamente, con 8 byte a disposizione abbiamo un bit per il segno, 16 bit per
l‟esponente (che risulta aumentato di 32767) e 47 bit per la mantissa.
Linguaggio C: possono essere definiti i seguenti tipi di dato reali
Tipo di dato
float
numero di byte
4 byte
double
8 byte
Intervallo valori ammessi
da ±1.40129846432481707e-45
a ±3.40282346638528860e+38
da 2.2250738585072014 * 10 -308
a 1.7976931348623157 * 10 308
Un numero di tipo float si dice in singola precisione, mentre un numero di tipo double è detto in
doppia precisione. Questo termine deriva dal fatto che poiché non possono essere rappresentati nel
computer i numeri irrazionali (ma nemmeno quelli razionali con troppe cifre decimali), per essi
possiamo usare solo un‟approssimazione, che sarà tanto più precisa quante più cifre decimali
riusciamo a rappresentare. Ovviamente, con più bit, si possono rappresentare più cifre decimali,
quindi, il tipo double risulta molto più preciso del tipo float.
RAPPRESENTAZIONE DELLE INFORMAZIONI ALFANUMERICHE
Si utilizza la codifica ASCII (American Standard Code for Information Interchange), che prevede di
associare un numero su 8 bit a ogni possibile simbolo (lettera, cifra, segno di punteggiatura,
caratteri speciali). Quindi, secondo la codifica ASCII, è possibile rappresentare fino a 256 simboli.
Ogni simbolo prende il nome di carattere. Essendo un carattere rappresentato su un numero di bit
pari a 8, esso può essere rappresentato anche come coppia di cifre esadecimali. I primi 128 codici
ASCII sono riportati nella pagina successiva. Per richiamare un particolare carattere conoscendo il
suo codice ASCII è possibile premere ALT + numero (sul tastierino numerico). Ad esempio, il
carattere „{„ corrisponde a ALT+123, mentre il carattere „}‟ corrisponde a ALT+125 (ci serviranno
molto nel linguaggio C).
Attualmente, poiché la globalizzazione ha comportato la necessità di comunicare sempre più spesso
con persone che usano altri alfabeti, diversi da quello latino (cirillico per i russi, ideogrammi cinesi
e giapponesi, ecc.), è stata ampliata la codifica ASCII da 8 a 16 bit, ed ha preso il nome di
UNICODE, che prevede la rappresentazione di 65536 simboli diversi.
Sequenze di caratteri sono dette stringhe, e vengono rappresentate in modi diversi a seconda dei
linguaggi di programmazione. Il Pascal e il Visual Basic, ad esempio, utilizzano il tipo string che
può avere un numero qualsiasi di caratteri. Il C, invece, nella sua versione “base”, non prevede un
tipo string: le sequenze sono vettori di caratteri (i vettori sono delle particolari strutture dati, che
studieremo tra un po‟). Solo il C++ successivamente ha introdotto delle estensioni del linguaggio
per supportare tale tipo di dato.
Tabella dei codici ASCII
Linguaggio C: può essere definito il seguente tipo di dato alfanumerico
Tipo di dato
unsigned char
char
numero di byte
1 byte
1 byte
Intervallo valori ammessi
0 ÷ 255
-128 ÷ 127
RAPPRESENTAZIONE DEI VALORI BOOLEANI
La rappresentazione dei valori booleani dipende dal particolare linguaggio di programmazione. Il
Pascal, ad esempio, dispone del tipo boolean e i valori che possiamo assegnare a variabili di questo
tipo sono true e false. In C la situazione è diversa: ogni tipo di dato può essere interpretato come
booleano, con la convenzione che il valore 0 equivale a falso, e un qualsiasi altro valore diverso da
0 equivale a vero.
Esempi:
valore booleano
15
vero
0
falso
-2
vero
0.18
vero