[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [home] [volume] [parte]


Capitolo 547.   Rappresentazione di valori numerici

La memoria di un elaboratore consente di annotare esclusivamente delle cifre binarie e in uno spazio di dimensione prestabilita e fissa. Questo capitolo descrive alcune forme di rappresentazione dei valori numerici, nell'ambito di queste limitazioni.

547.1   Codifica delle singole cifre

Un valore numerico potrebbe essere espresso come una stringa di caratteri, corrispondenti alle cifre numeriche che lo rappresentano secondo la notazione in base dieci. Naturalmente, una rappresentazione del genere implica uno spreco di spazio nel sistema di memorizzazione e richiede una trasformazione prima di poter procedere all'esecuzione di calcoli numerici.

Esistono diverse forme di rappresentazioni numeriche, intese come sequenze di cifre in base dieci, che utilizzano quattro bit per ogni cifra. Il sistema più comune è noto con il nome BCD: Binary coded decimal.

I sistemi di rappresentazione numerica che utilizzano quattro bit per ogni cifra di un valore in base dieci, si utilizzano per esempio nel linguaggio COBOL, per le variabili scalari di tipo computational.

Tabella 547.1. Alcune codifiche per la rappresentazione di cifre numeriche (in base dieci) a gruppi di quattro bit.

Cifra
decimale
Codice BCD (8421) Codice «eccesso 3» Codice 2421 Codice 5211 Codice 631-1 Codice 732-1
0 00002 00112 00002 00002 00002
00112
00002
1 00012 01002 00012 00012
00102
00102 00112
2 00102 01012 00102
10002
01002
00112
01012 00102
3 00112 01102 00112
10012
01012
01102
01002 01002
4 01002 01112 01002
10102
01112 01102 01112
5 01012 10002 01012
10112
10002 10012 01102
6 01102 10012 01102
11002
10102
10012
10002 10012
7 01112 10102 01112
11012
10112
11002
10102 10002
8 10002 10112 11102 11102
11012
11012 10112
9 10012 11002 11112 11112 11002
11112
10102

La codifica BCD e altre sono codici pesati, in quanto a ogni bit viene attribuito un peso, da sommare per determinare il valore. I pesi per la codifica BCD sono 8, 4, 2 e 1; pertanto, il codice BCD 10012 corrisponde a 1*8+0*4+0*2+1*1 = 9. Nella tabella riepilogativa, i codici pesati sono: BCD, 2421, 5211, 631-1 e 732-1. I nomi usati per questi codici sono costituiti dalla sequenza dei pesi stessi.

Alcuni codici pesati prevedono la rappresentazione di qualche cifra in più in un modo alternativo. Per esempio, nel codice 2421, il numero due si può ottenere sia come 10002, sia come 00102.

I codici pesati come BCD (ovvero 8421), 2421 e 5211, prevedono pesi positivi; i codici come 631-1 e 732-1, prevedono anche pesi negativi. Per esempio, con il codice 732-1, si ottiene il valore uno con il codice 00112, perché il secondo bit (a destra) vale come il numero due, mentre il primo bit (a destra) sottrae una unità.

Dei codici che appaiono nella tabella, il codice a eccesso tre, non è un codice pesato, in quanto corrisponde al codice BCD, a cui si aggiunge il valore tre.

È necessario sottolineare che il codice BCD, a seconda del contesto, può essere riferito anche a un codice a otto bit, dove i primi quattro, più significativi, sono posti a zero.

547.2   Rappresentazione binaria di numeri interi senza segno

Quando si rappresentano dei valori numerici in forma binaria, senza passare per una conversione di ogni singola cifra decimale, si usa tutta la sequenza di bit per il valore. La rappresentazione di un valore intero senza segno coincide normalmente con il valore binario contenuto nella variabile. Pertanto, una variabile della dimensione di 8 bit, può rappresentare valori da zero a 28-1:

000000002 (010)
000000012 (110)
000000102 (210)
...
111111102 (25410)
111111112 (25510)

547.3   Rappresentazioni binarie obsolete di numeri interi con segno

Un numero binario, inserito nella memoria di un elaboratore, può contenere esclusivamente cifre numeriche; pertanto, la rappresentazione del segno può avvenire solo attraverso cifre numeriche. A partire approssimativamente dal 1965, il segno di un numero intero si rappresenta attraverso il complemento alla base (complemento a due) che ha delle proprietà importanti, ma per comprenderle occorre vedere quali sono state le alternative precedenti.

Il primo modo utilizzato per rappresentare un numero intero con segno è stato quello di attribuire a un bit (probabilmente quello più significativo) il ruolo di indicatore del segno. Per esempio, 000010102 andrebbe interpretato come +1010, mentre 100010102 rappresenterebbe il valore -1010. In questo modo, disponendo di otto cifre binarie, dovendone riservare una per il segno, si potrebbero rappresentare valori da -127 (111111112) a +127 (011111112); inoltre, lo zero potrebbe essere rappresentato indifferentemente come 000000002 o come 10000002.

Il secondo metodo (usato per esempio nel PDP-1) prevede la rappresentazione dei numeri negativi come complemento a uno del valore positivo corrispondente. Il complemento a uno si ottiene invertendo le cifre del numero binario. In questo modo, per esempio, 000010102 rappresenterebbe sempre il valore +1010, mentre 111101012 corrisponderebbe a -1010. Anche in questo caso la prima cifra rappresenta il segno (dove la cifra uno indica un valore negativo), ma il segno si aggiorna automaticamente con la semplice inversione del valore. Utilizzando il complemento a uno per rappresentare i valori negativi, come nel caso precedente, su otto cifre complessive si possono indicare valori da -127 a +127 e lo zero si può rappresentare ancora in due modi differenti: 000000002 o 111111112.

Disponendo di una variabile per rappresentare valori interi con segno, considerato che il bit più significativo serve a rappresentare il segno stesso, si dispone di un bit in meno per indicare il valore. Pertanto, se si dispone di n bit, si possono rappresentare valori fino a n-1 bit, ovvero valori fino a 2(n-1)-1. Per i numeri negativi, il calcolo è lo stesso, anche se si considera che si fa riferimento a valori complementati: si può rappresentare fino a -(2(n-1)-1).

Il complemento alla base (ovvero il complemento a due) che è invece il metodo attuale per rappresentare i valori interi negativi, ha i vantaggi del metodo del complemento a uno, ma in più ha un solo modo per rappresentare lo zero.

547.4   Complemento a due

Attualmente, per rappresentare valori interi con segno (positivo o negativo), si utilizza il metodo del complemento alla base, ovvero del complemento a due, dove il primo bit indica sempre il segno. Il complemento a due si ottiene facilmente calcolando prima il complemento a uno e poi aggiungendo una unità al risultato. Per esempio, se si prende un valore positivo rappresentato in otto cifre binarie come 000101002 (pari a +2010), il complemento a uno è 111010112; aggiungendo una unità si ottiene il complemento a due: 111011002.

Utilizzando questo metodo, per cambiare di segno a un valore è sufficiente calcolarne il complemento a due (esattamente come si farebbe con il metodo del complemento a uno). Lo si verifica facilmente: riprendendo l'esempio già fatto, partendo da -2010 che si rappresenta come 111011002, si calcola prima il complemento a uno, ottenendo così 000100112, quindi si somma una unità e si ottiene 000101002, pari a +2010.

Con il complemento a due, disponendo di n cifre binarie, si possono rappresentare valori da -2(n-1) a +2(n-1)-1 ed esiste un solo modo per rappresentare lo zero: quando tutte le cifre binarie sono pari a zero. Infatti, rimanendo nell'ipotesi di otto cifre binarie, il complemento a uno di 000000002 è 111111112, ma aggiungendo una unità per ottenere il complemento a due si ottiene di nuovo 000000002, perdendo il riporto.

Si osservi che il valore negativo più grande rappresentabile non può essere trasformato in un valore positivo corrispondente, perché si creerebbe un traboccamento. Per esempio, utilizzando sempre otto bit (segno incluso), il valore minimo che possa essere rappresentato è 10000002, pari a -12810, ma se si calcola il complemento a due, si ottiene di nuovo lo stesso valore binario, che però non è valido. Infatti, il valore positivo massimo che si possa rappresentare in questo caso è solo +12710.

Figura 547.2. Confronto tra due valori interi con segno.

bin

Figura 547.3. Valori massimi rappresentabili con soli otto bit.

bin max

Il meccanismo del complemento a due ha il vantaggio di trasformare la sottrazione in una semplice somma algebrica.

547.5   Rappresentazione binaria di numeri in virgola mobile

Una forma diffusa per rappresentare dei valori molto grandi, consiste nell'indicare un numero con dei decimali moltiplicato per un valore costante elevato a un esponente intero. Per esempio, per rappresentare il numero 123 000 000 si potrebbe scrivere 123·106, oppure anche 0,123·109. Lo stesso ragionamento vale anche per valori molti piccoli; per esempio 0,000 000 123 che si potrebbe esprimere come 0,123·10-6.

Per usare una notazione uniforme, si può convenire di indicare il numero che appare prima della moltiplicazione per la costante elevata a una certa potenza come un valore che più si avvicina all'unità, essendo minore o al massimo uguale a uno. Pertanto, per gli esempi già mostrati, si tratterebbe sempre di 0,123·10n.

Per rappresentare valori a virgola mobile in modo binario, si usa un sistema simile, dove i bit a disposizione della variabile vengono suddivisi in tre parti: segno, esponente (di una base prestabilita) e mantissa, come nell'esempio che appare nella figura successiva.(1)

Figura 547.4. Ipotesi di una variabile a 16 bit per rappresentare dei numeri a virgola mobile.

virgola mobile

Nella figura si ipotizza la gestione di una variabile a 16 bit per la rappresentazione di valori a virgola mobile. Come si vede dallo schema, il bit più significativo della variabile viene utilizzato per rappresentare il segno del numero; i sette bit successivi si usano per indicare l'esponente (con segno) e gli otto bit finali per la mantissa (senza segno perché indicato nel primo bit), ovvero il valore da moltiplicare per una certa costante elevata all'esponente.

Quello che manca da decidere è come deve essere interpretato il numero della mantissa e qual è il valore della costante da elevare all'esponente indicato. Sempre a titolo di esempio, si conviene che il valore indicato nella mantissa esprima precisamente «0,mantissa» e che la costante da elevare all'esponente indicato sia 16 (ovvero 24), che si traduce in pratica nello spostamento della virgola di quattro cifre binarie alla volta.(2)

Figura 547.5. Esempio di rappresentazione del numero 0,051 513 671 875 (211·16-3), secondo le convenzioni stabilite. Si osservi che il valore dell'esponente è negativo ed è così rappresentato come complemento alla base (due) del valore assoluto relativo.

somma

Naturalmente, le convenzioni possono essere cambiate: per esempio il segno lo si può incorporare nella mantissa; si può rappresentare l'esponente attraverso un numero al quale deve essere sottratta una costante fissa; si può stabilire un valore diverso della costante da elevare all'esponente; si possono distribuire diversamente gli spazi assegnati all'esponente e alla mantissa.

547.6   Rappresentazione in virgola mobile IEEE 754

Per la rappresentazione dei valori in virgola mobile esiste uno standard importante, IEEE 754 (ripreso anche da altri enti di standardizzazione), con il quale si definiscono due formati, per la precisione singola e doppia. Secondo questo standard, un valore in virgola mobile a precisione singola richiede 32 bit, mentre per la precisione doppia sono necessari 64 bit. Per prima cosa si definisce un «numero normalizzato», corrispondente a:(3)

1,significante2 × 2esponente

Di questo si utilizza solo il significante (mantissa) e l'esponente (caratteristica), omettendo il numero uno iniziale. Nella forma prevista dallo standard IEEE 754 si annota separatamente il segno del numero, quindi l'esponente, che però è «polarizzato» (nel senso che al valore dell'esponente originario occorre sommare un certo valore fisso), quindi si mettono le cifre del significante (tutte quelle che possono starci). Si osservi che il significante viene indicato sempre come valore assoluto, pertanto non si applica il complemento per i valori negativi; inoltre, l'esponente viene indicato sommando al valore originale un numero fisso che è costituito da tutti i bit a uno, tranne quello più significativo (quando l'esponente è formato da otto bit, il numero da sommare è 011111112, pari a 12710; quando l'esponente è formato da 11 bit, il numero da sommare è 011111111112, pari a 102310).

Figura 547.6. IEEE 754 a precisione singola.

IEEE 754 a precisione singola

Figura 547.7. IEEE 754 a precisione doppia.

IEEE 754 a precisione doppia

Conviene fare un esempio con la precisione singola: si vuole rappresentare il valore 21,1110. Si procede convertendo separatamente la parte intera e poi quella decimale. Il numero 2110 si converte facilmente in 101012, mentre per la parte decimale occorre fare qualche calcolo in più:

0,11 × 2 = 0,22 → ,02
0,22 × 2 = 0,44 → ,002
0,44 × 2 = 0,88 → ,0002
0,88 × 2 = 1,76 → ,00012
0,76 × 2 = 1,52 → ,000112
0,52 × 2 = 1,04 → ,0001112
0,04 × 2 = 0,08 → ,00011102
0,08 × 2 = 0,16 → ,000111002
0,16 × 2 = 0,32 → ,0001110002
0,32 × 2 = 0,64 → ,00011100002
0,64 × 2 = 1,28 → ,000111000012
0,28 × 2 = 0,56 → ,0001110000102
0,56 × 2 = 1,12 → ,00011100001012
0,12 × 2 = 0,24 → ,000111000010102
0,24 × 2 = 0,48 → ,0001110000101002
0,48 × 2 = 0,96 → ,00011100001010002
0,96 × 2 = 1,92 → ,000111000010100012
0,92 × 2 = 1,84 → ,0001110000101000112
0,84 × 2 = 1,68 → ,00011100001010001112
0,68 × 2 = 1,36 → ,000111000010100011112
0,36 × 2 = 0,72 → ,0001110000101000111102
...

Pertanto, 21,1110 corrisponde approssimativamente a 10101,0001110000101000111102. Per normalizzare il numero occorre spostare la virgola a sinistra e moltiplicare per una potenza di due: 1,01010001110000101000111102 × 24.

A questo punto si prelevano 23 cifre dopo la virgola, ma si richiede un arrotondamento (in questo caso avviene per eccesso), pertanto le cifre che compongono il significante diventano: 010100011100001010010002. L'esponente va sommato al valore costante stabilito: 4+127 = 131. Quindi l'esponente si rappresenta così: 100000112. Trattandosi di un numero positivo, il bit del segno deve essere zero. Ecco il numero in virgola mobile, a precisione singola, espresso secondo la notazione standard (gli spazi aggiunti servono a facilitarne la lettura):

0 10000011 010100011100001010010002

Con questo metodo, un numero a precisione singola può avere un valore assoluto da 12 × 2-126 a 1,1111...2 × 2+127; mentre un numero a precisione doppia può avere un valore assoluto da 12 × 2-1 022 a 1,1111...2 × 2+1 023. Quando si devono rappresentare valori molto bassi, si azzerano i bit dell'esponente e si usa una forma «denormalizzata» di questo tipo per la precisione singola:

0,significante2 × 2-127

Per la precisione doppia:

0,significante2 × 2-1 024

547.7   Ordine dei byte(4)

Generalmente si distinguono i microprocessori in base a una caratteristica legata al modo di ordinare i bit di un numero, presi a gruppi di otto. In pratica, di norma la memoria centrale degli elaboratori è organizzata a celle di otto bit (un byte), mentre il microprocessore è in grado di elaborare dati numerici con una quantità di bit maggiore (ma sempre multipli di otto). Nel momento in cui il microprocessore accede alla memoria centrale per leggere o scrivere un valore, lo fa secondo un ordine che dipende dalla sua progettazione.

Supponendo di avere a che fare con il valore 13579BDF16, se il microprocessore lo memorizza secondo la stessa sequenza (ovvero memorizza i byte 1316, 5716, 9B16 e DF16), allora si dice che la sua architettura è big endian; diversamente, se il microprocessore memorizza invertendo la sequenza di byte (quindi DF16, 9B16, 5716 e 1316) si dice che questo lavora in modalità little endian.

Naturalmente, il microprocessore che scrive in memoria un valore secondo una sequenza di byte invertita, quando va a leggerlo dalla memoria si aspetta di trovarlo invertito nello stesso modo.

Sia chiaro che, all'interno di ogni byte, l'ordine dei bit non viene modificato. Inoltre, nel momento in cui si pensa a un'elaborazione all'interno del microprocessore, con dati contenuti nei suoi registri, non ha importanza conoscere qual è l'ordine dei byte.

547.8   Riferimenti


1) Nel contesto riferito alla definizione di un numero in virgola mobile, si possono usare indifferentemente i termini mantissa o significante, così come sono indifferenti i termini caratteristica o esponente.

2) Si osservi che lo standard IEEE 754 utilizza una «mantissa normalizzata» che indica la frazione di valore tra uno e due: «1,mantissa.

3) Considerato che si tratta di un numero da esprimere in base due, il valore che viene moltiplicato per la potenza di due è un numero che va da uno a due.

4) Per completezza, questa sezione riprende un concetto già descritto in un altro capitolo, precisamente in 545.6.


Appunti di informatica libera 2008 --- Copyright © 2000-2008 Daniele Giacomini -- <appunti2 (ad) gmail·com>


Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome rappresentazione_di_valori_numerici.htm

[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [home]

Valid ISO-HTML!

CSS validator!

Gjlg Metamotore e Web Directory