Analogamente all'aspetto della rappresentazione si
può ragionare sull'aspetto della registrazione o memorizzazione
e quello dell'elaborazione.
Un grande vantaggio delle tecnologie digitali è che le grandezze
rappresentate digitalmente possono venire elaborate in maniera in
genere molto più semplice e flessibile.
Inoltre una grandezza, o un insieme anche grandissimo di grandezze,
rappresentate digitalmente, potranno essere memorizzate o duplicate
digitalmente senza mai degradarsi: si tratterà essenzialmente di
copiare dei numeri.
Il concetto di digitale può pertanto identificarsi col concetto di numerico.
ossia, arrivati nuovamente all'ultimo simbolo (cifra) disponibile nella
posizione di destra, il 9, torniamo ad utilizzare lo 0, e facciamo
"scattare avanti" la cifra immediatamente a sinistra con la cifra
successiva. Ma anche qui siamo arrivati al 9, quindi torniamo a
utilizzare lo 0 e mettiamo un altro 1 a sinistra. E così via.
Sappiamo inoltre benissimo che scrivere degli 0 a sinistra di un numero
non ne cambia il valore per cui, ad esempio:
000935 = 935
Avendo, ad esempio, a disposizione 4 posizioni ove disporre le cifre
(ossia se scriviamo un numero di 4 cifre), si potranno avere 104 diverse combinazioni, e quindi 104 =10000 diversi numeri: da
0000 a 9999.
La numerazione binaria funziona esattamente nello stesso modo, anziché
utilizzare 10 diversi simboli o cifre, ne usa solamente 2.
Di solito si usano "0" e "1", ma si potrebbe usare "vero" e "falso",
"pieno" e "vuoto", "testa" e "croce" o "mela" e "pera".
Per comodità di lettura, in questo sito, quando scriveremo un numero binario useremo un font un po' diverso, un "monospaced", e separeremo con uno spazio i gruppi di 4 cifre binarie.
La base della numerazione decimale è ovviamente 10, quella della
numerazione binaria è 2.
La regola per la numerazione è la stessa: quando non abbiamo più
simboli a disposizione (cioé siamo arrivati a 1), usiamo lo 0, e
facciamo "scattare avanti" la cifra immediatamente a sinistra, così:
0
1
10
11
100
101
110
111
1000
...
Anche qui ovviamente scrivere degli 0 a sinistra di un numero non ne
cambia il valore per cui, ad esempio:
0011 = 11
Avendo, ad esempio, a disposizione 8 posizioni ove disporre le cifre
(ossia se scriviamo un numero a 8 cifre binarie) si potranno avere 28 diverse combinazioni, e quindi 28 = 256 diversi numeri: da
0000 0000 a 1111 1111, corrispondenti a 0 e 255 nella numerazione
decimale.
La regola generale, che vale anche per i sistemi di numerazione a base
diversa da 2 e da 10 è:
numeri possibili = (base della numerazione) quantità di cifre
Un sistema di numerazione spesso usato in informatica, come vedremo, è
anche il sistema hexadecimale, a base 16.
In informatica la cifra binaria prende il nome di bit.
Un multiplo del bit composto da 8 bit, è il Byte.
1 è un bit
0110 è un numero di 4 bit
0010 1100 è un numero di 8 bit. Corrisponde a un Byte
0110 0110 1100 1111 è un numero di 16 bit, ossia di 2 Byte
3 |
0 |
4 |
7 |
migliaia | centinaia | decine | unità |
x 103 | x 102 | x 101 | x 100 |
x 1000 | x 100 | x 10 | x 1 |
3000 |
0 |
40 |
7 |
1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 |
... | ... | ... | ... | ottetto | quartetto | coppia | unità |
x 27 | x 26 | x 25 | x 24 | x 23 | x 22 | x 21 | x 20 |
x 128 | x 64 | x 32 | x 16 | x 8 | x 4 | x 2 | x 1 |
128 | 0 | 0 | 16 | 0 | 4 | 2 | 1 |
In pratica moltiplico i numeri della prima riga (che sono le cifre binarie 1 o 0) per i valori della penultima riga (che sono le potenze del 2) e ottengo i valori dell'ultima riga, che vanno sommati tra loro per ottenere il numero decimale.
128 + 16 + 4 +2 + 1 = 151
Esiste un metodi pratico molto agevole. Impariamolo con un esempio:
Prendiamo ad esempio il numero decimale 105 di cui vogliamo conoscere la corrispondente forma binaria.
Cominciamo a dividerlo per 2, ottenendo un intero con il suo resto:
105 : 2 = 52, con il resto di 1
Il resto corrisponde alla cifra binaria meno significativa, ossia quella che si scrive più a destra.
Continiamo a dividere per 2, e registriamo i resti, che corrispondono alle cifre binarie che scriveremo via via verso sinistra. Sarà agevole fare una tabellina:
numero di partenza e risulati della divisione per 2 | ||
105 | resto | spiegazione |
52 | 1 | 105 : 2 = 52 con resto 1 |
26 | 0 | 52 : 2 = 26 con resto 0 |
13 | 0 | 26 : 2 = 13 con resto 0 |
6 | 1 | 13 : 2 = 6 con resto 1 |
3 | 0 | 6 : 2 = 3 con resto 0 |
1 | 1 | 3 : 2 = 1 con resto 1 |
0 | 1 | 1 : 2 = 0 con resto 1 |
Ricordarsi di arrivare alla fine! L'ultima divisione è sempre 1 : 2 = 0 con resto 1.
I resti quindi formano le cifre del numero binario (il resto più in basso è la cifra binaria più a sinistra!): 110 1001
Se provassimo ad andare avanti a dividere avremmo sempre 0 : 2 = 0 con resto 0, quindi metteremmo davanti alla prima cifra significativa (che è sempre 1) una serie di 0, che non cambierebbero il valore del numero. Il numero decimale 00705 vale come il numero decimale 705, così come il numero binario 110 1001 vale come il numero binario 0000 0110 1001
Qui si può effettuate automaticamente la conversione:
k | kilo | 1.0001 | =103 | =1˙000 |
= mille |
M |
mega |
1.0002 | =106 | =1˙000˙000 |
= un milione |
G |
giga |
1.0003 | =109 | =1˙000˙000˙000 |
= un miliardo |
T |
tera |
1.0004 | =1012 | =1˙000˙000˙000˙000 |
= mille miliardi |
P |
peta |
1.0005 | =1015 | =1˙000˙000˙000˙000˙000 |
= un milione di miliardi |
Quindi si avranno, come mutipli i kb (1˙000 bit) e i kB (1˙000 Byte), i Mb e i MB, i Gb e i GB, i Tb e i TB.
Per i bit e i Byte si usano però, a volte, dei multipli leggermente diversi. Infatti, anziché usare la base 1˙000 si usa la base 1˙024. La ragione è che, poiché bit e Byte hanno a che fare con il sistema binario, è comodo usare, anziché la base 1˙000, la base 1˙024, che è assai prossima al valore decimale mille, ma, essendo 1010 = 1˙024, è comodamente esprimibile con il numero binario:
10 0000 0000 0000 (un " 1" seguito da dieci " 0 ").
I mutipli in questo caso si chiamano kibibyte, mebibate, gibibyte, tebybyte, i cui simboli sono ndicati nella tabella qui sotto
In questo caso i multipli risultano essere, per i Byte:
KiB | kibiByte | 1.0241 | =210 | =1.024 | ≈ mille |
MiB |
mebiByte |
1.0242 | =220 | = 1.048.576 | ≈ un milione |
GiB |
gibiByte |
1.0243 | =230 | = 1.073.741.824 |
≈ un miliardo |
TiB |
tebiByte |
1.0244 | =240 | =1.099.511.627.776 |
≈ mille miliardi |
PiB |
pebiByte |
1.0245 | =250 | =1.125.899.906.842.620 |
≈ un milione di miliardi |
Un sistema di numerazione che viene spesso usato in informatica è il
sistema esadecimale, ossia a base 16.
La cosa può sembrare un'astrusa complicazione, ma in realtà risulta
abbastanza semplice e comoda. In grafica è importante per la codifica
dei colori (come vedremo più avanti)
La numerazione esadecimale usa, ovviamente, 16 diversi simboli, o
cifre. Si usano le cifre:
0 1 2 3 4 5 6 7 8 9 A B C D E F
Quando si esprime un numero nel sistema esadecimale lo si usa precedere
da un prefisso che fa comprendere che quello che segue è un numero
esadecimale.
Se scrivessimo semplicemente 831 non capiremmo se stiamo scrivendo un
numero decimale o esadecimale.
Le convenzioni dipendono dallo specifico linguaggio informatico
utilizzato. Nelle codifiche di colore in HTML si fa precedere, ad
esempio, al simbolo "#", che è la convenzione che utilizzeremo negli
esempi che seguono.
Allora se scrivessimo 831 intenderemmo un numero decimale,
mentre se scrivessimo #831 intenderemmo un numero esadecimale (che
corrisponde ,capiremo poi perché, a 2097 nel sistema decimale, e 1000 0011 0001
nel sistema
binario).
Nel sistema esadecimale valgono le stesse regole del conteggio viste
per i sistemi decimale e binario, ma si osservi anche che:
16 = 24
quindi con 4 bit si possono esprimere 16 diversi valori, da 0000 a
1111, corrispondenti ai valori da 0 a 15 nel sistema decimale, da #0 a #F nel sistema esadecimale.
Quindi ogni cifra esadecimale corrisponde a un gruppo di quattro bit,
secondo la corrispondenza:
esadecimale | binario | decimale |
#0 | 0000 |
0 |
#1 | 0001 |
1 |
#2 | 0010 |
2 |
#3 | 0011 |
3 |
#4 | 0100 |
4 |
#5 | 0101 |
5 |
#6 | 0110 |
6 |
#7 | 0111 |
7 |
#8 | 1000 |
8 |
#9 | 1001 |
9 |
#A | 1010 |
10 |
#B | 1011 |
11 |
#C | 1100 |
12 |
#D | 1101 |
13 |
#E | 1110 |
14 |
#F | 1111 |
15 |
La codifica ASCII utilizza 7 bit per codificare i caratteri.
Con 7 bit si possono codificare 27 = 128 differenti
caratteri.
128 caratteri sono sufficienti a codificare 26 caratteri dell'alfabeto
inglese, maiuscoli e minuscoli, 10 cifre decimali, un certo numero di
segni di interpunzione (. , ! ? "spazio" ...) e un certo numero di
caratteri non stampabili, corrispondenti comandi necessari alla
scrittura informatica e alla trasmissione dei dati ("a capo", "su",
"giù", "fine"...). In più restano un certo numero di caratteri non
utilizzati.
Eccone solo alcuni:
Così ad esempio, il codice 000
1010 corrisponde al comando " a capo" ("line feed"), il
codice 010 0000 corrisponde al carattere "spazio", il codice 011 0001 (che come numero decimale corrisponde al numero 49) corrisponde al
carattere "1", il codice 100 0010 al carattere "B" maiuscola e così via.
I caratteri stampabili (quindi anche lo "spazio") vanno dalla codifica
decimale 32 alla 126, si hanno quindi 95 caratteri stampabili.
Vedi tabella completa
della codifica ASCII
La codifica ASCII usa 7 bit. Poiché
tipicamente i dati vengono
trasmessi in gruppi di 8 bit, corrispondenti a un Byte, rimaneva un bit
libero, i protocolli di trasmissione dati prevedevano di utilizzare
questo bit libero inserendo un bit iniziale che aveva funzione di
controllo, detto bit di parità.
Il bit di parità deve fare somma pari con gli altri 7 bit. Se nella
trasmissione dati la somma del Byte dà un numero dispari significa che
c'é stato sicuramente un errore di trasmissione.
Ad esempio:
Il carattere "r" corrisponde alla codifica 111
0010. Aggiungendo il bit di
parità si ha:
0111 0010
Attenzione! Nelle codifiche dei caratteri non vale la regola che è indifferente mettere o meno a sinistra le cifre 0. Se lo zero ci deve essere non lo si può omettere!
Il carattere "W" corrisponde alla codifica 101
0111. Aggiungendo il bit di
parità si ha:
1101 0111
Se un Byte ha codifica 1111 0010 contiene sicuramente un errore (ci sono cinque "1")
Il bit di parità però dice che c'è un errore, ma non dice dov'è, né lo corregge, e se gli
errori sono due nello stesso Byte non sono evidenziabili. È quindi un
sistema di segnalazione dell'errore ormai superato da sistemi di
correzione più efficaci.
Attualmente, per garantire la compatibilità della codifica ASCII con le
codifiche attuali (vd. più avanti) si precede ai sette bit non il bit
di parità ma il bit "0", che indica che ciò che segue è un carattere
ASCII.
128 possibili caratteri sono evidentemente troppo pochi, e per questo
motivo sono state studiate moltissimi tipi di codifiche più estese.
Questo però ha portato ad avere dei grossi problemi di compatibilità
tra codifiche (quante volte navigando in internet incappiamo in
caratteri errati o non decodificati: lo sviluppatore non si è
probabilmente preoccupato di approfondire i problemi di compatibilità
del suo sito).
L'obiettivo delle codifiche Unicode è quello di superare questi
problemi e al tempo stesso di codificare un enorme numero di caratteri, anche di
alfabeti diversi da quello latino.
La codifica Unicode UTF-8 è quella diventata lo standard per il web
stabilito dal consorzio W3C (ma questo non vuol dire che, purtroppo,
tutti i siti web utilizzino questo standard).
Con questa codifica ogni carattere usa un numero variabile di Byte da 1
a 4, ed è compatibile con la codifica ASCII.
Il grande vantaggio della codifica UTF-8 è che è a lunghezza variabile: per codificare i caratteri più comuni (che sono gli ASCII) usa un Byte per carattere, per molti caratteri, meno comuni, due Byte per carattere, e può usare fino a quattro Byte per carattere per i caratteri veramente poco comuni.
Se un applicazione, come ad esempio un browser, che utilizza UTF-8,
incontra il codice:
0101 0111
capisce, dal fatto che inizia con uno "0",
che si tratta di un
carattere codificato con un solo Byte, quindi corrispondente a un
carattere ASCII che è: 101 0111
corrispondente al carattere latino "W", come in ASCII.
Il primo bit (che è 0) ha quindi funzione di controllo (dice in quanti
Byte è codificato il carattere), gli altri 7 corrispondono al carattere
vero e proprio.
Un carattere UTF di un solo Byte codifica quindi solo i caratteri ASCII, e quindi, come per gli ASCII, permette di codificare 128 caratteri (di cui 95 stampabili). La sua struttura è questa:
0xxx xxxx
che significa che il primo bit è sempre 0, gli altri (le x) possono avere valori 0 o 1 e sono i bit utilizzabili.
Se invece l'applicazione incontra un Byte che inizia con "110"
capisce che si tratta di
un carattere codificato con 2 Byte (quindi non un carattere ASCII), e
quindi dovrà considerare anche il Byte successivo (che dovrà iniziare
cper forza con "10").
I tre bit iniziali (110)
nel primo Byte hanno la funzione di dire che il carattere è di 2 Byte,
i mentre i due bit iniziali del Byte successivo (10) hanno la funzione di dire: "questo non è
il Byte iniziale della codifica del carattere".
Se quindi leggendo il Byte successivo abbiamo, ad esempio:
1101 0000 1001 0110 questi due Byte, insieme,
corrispondono al carattere cirillico Ж
Con due Byte si codificano molti caratteri dell'alfabeto latino che non rientrano nella codifica ASCII, come (ad esempio) le lettere accentate e anche (ma non solo), gli alfabeti greco,
cirillico, copto, armeno, ebraico, arabo.
La struttura di un carattere UTF-8 di due Byte è questa:
110x xxxx 10xx xxxx
che significa che i primi tre bit del primo Byte sono sempre 110, i primi due bit del secondo Byte sono sempre 10, gli altri bit (le x) possono avere valori 0 o 1.
Poiché le x (che corrispondono ai bit utilizzabili) sono in tutto 11, con due Byte è possibile codificare 2 11 = 2˙048 caratteri (ma non tutti stampabili).Se invece l'applicazione incontra un Byte che inizia con 1110,
questo sta a significare
che la codifica usa 3 Byte (i due Byte successivi dovranno iniziare
con 10).
Con 3 Byte si possono codificare anche (ma non solo) i più comuni
caratteri del cinese, giapponese e coreano.
Ad esempio il codice:
1110 1010 1011 1001 1001 0010
corrisponde
al
carattere Hangŭl (alfabeto coreano) 깑
Si noti che il primo Byte inizia con 1110 e gli altri due con 10.
Anche il simbolo dell'Euro (€) necessita di tre Byte, il suo codice UTF-8 è:
1110 0010 1000 0010 1010 1100
La struttura di un carattere UTF-8 di tre Byte è questa:
1110 xxxx 10xx xxxx 10xx xxxx
Poiché le x (i bit utilizzabili) sono in tutto 16, con tre Byte è possibile codificare 216 = 65˙536 caratteri.
Se invece l'applicazione incontra un Byte che inizia con 1111 0,
questo sta a significare
che la codifica usa 4 Byte (gli altri tre dovranno inziare con 10).
Con 4 Byte si possono codificare anche (ma non solo) dei caratteri meno
comuni del cinese, giapponese e coreano, alcuni sistemi di scrittura
antichi, simboli matematici e emoj. Molti codici sono lasciati liberi
per futuri sviluppi.
La struttura di un carattere UTF-8 di quattro Byte è invece questa:
1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx
Poiché le x (i bit utilizzabili) sono in tutto 21, con quattro Byte è possibile codificare 221 = 2˙097˙152 caratteri.