Corso di C con Linux

Rappresentazione di numeri interi e reali

 

Nella scorsa lezione abbiamo appreso che i numeri interi possono essere rappresentati all’interno del calcolatore in due modi distinti:
i) modulo e segno
ii) complemento a 2

Per la rappresentazione in modulo e segno si procede nel seguente modo:
1-  A partire dal numero decimale si effettua la conversione in binario dividendo ciclicamente il modulo per 2 e prendendo i resti della divisione finché il risultato non è 0;
2-  si pone ad 1 il primo bit della stringa di rappresentazione se il numero è negativo, 0 se è positivo;
3- si pongono nella stringa gli altri n bit ottenuti dalla divisione, inserendo degli zeri a sinistra fino a completare la stringa.
Vediamo due esempi.
Supponiamo di utilizzare 8 bit per rappresentare un intero e di dover codificare i numeri +4 e –5.

Per il numero +4:
- prendo 4 e lo divido per 2, ottengo 2 con resto  0;
- divido il risultato precedente (2) per 2, ottengo 1 con resto 0;
- divido 1 per 2, ottengo 0 con resto 1.
Il numero binario corrispondente al modulo 4 è 100 e poiché il numero è positivo il primo bit sarà 0.
Dunque il numero +4 rappresentato in modulo e segno con 8 bit è 00000100 (in grassetto sono evidenziati il bit di segno e la codifica del modulo).
Analogamente procediamo per il numero -5:
- 5 : 2 = 2 resto 1;
- 2 : 2 = 1 resto 0;
- 1 : 2 = 0 resto 1.
Il numero binario corrispondente al modulo 5 è 101 e poiché il numero è negativo il primo bit sarà 1.
Il numero -5 rappresentato in modulo e segno con 8 bit è 10000101.

Per la rappresentazione in complemento a 2 si procede nel seguente modo.
Sia n la dimensione massima della stringa di bit mediante la quale rappresentiamo un intero (generalmente n vale 16, 32 o 64).

Sia a un generico intero compreso tra -2n-1 e 2n-1:
- Se a >= 0 si converte in binario;
- Se a < 0 si calcola a + 2n e si converte il risultato in binario senza segno su n bit.
Supponiamo che sia n = 4 (valore improbabile ma utile per semplificare il calcolo) e di dover rappresentare in complemento a 2 il numero a = -5.
Poiché a è negativo, gli sommiamo il valore 24 = 16 e otteniamo il valore 11, che convertiamo in binario con il metodo del modulo e segno:

11 : 2 = 5 resto 1;
 5 : 2 = 2 resto 1;
 2 : 2 = 1 resto 0;
 1 : 2 = 1;

Dunque il valore –5 rappresentato in complemento a 2 con 4 bit è 1011.
In generale con n bit è possibile rappresentare un intero il cui valore è compreso tra -2n-1-1 e +2n-1-1 se si utilizza la rappresentazione in modulo e segno, tra -2n-1 e 2n-1-1 se si utilizza il complemento a due.
Nelle tabelle seguenti sono mostrati i range di valori del tipo di dati int al variare del numero di bit usati per la codifica per entrambe le rappresentazioni.

Numero di bit

Modulo e segno

8

da –127 a +127

16

da –32.767 a +32.767

32

da –2.147.483.647 a +2.147.483.647

64

da –9.223.372.036.854.775.807 a +9.223.372.036.854.775.807

Numero di bit

Complemento a due

8

da –128 a +127

16

da –32.768 a +32.767

32

da –2.147.483.648 a +2.147.483.647

64

da –9.223.372.036.854.775.808 a +9.223.372.036.854.775.807



In C i numeri reali vengono rappresentati mediante la notazione scientifica.
Un numero reale N espresso nella notazione scientifica (detta floating point) assume la forma:

N = m * (b elevato al numero e)

dove b è la base, m la mantissa, ed e l'esponente.
La maggior parte dei calcolatori rappresenta i numeri reali secondo lo standard IEEE 754, che tratta solo valori reali normalizzati, cioè aventi mantissa costituita da un solo bit di valore 1.
Per questo motivo si trascura la parte intera della mantissa e si considera solo la sua parte frazionaria.

In C per i tipi di dati float e double si usano rispettivamente le rappresentazioni in singola e doppia precisione, organizzate secondo quanto descritto in tabella:

Tipo di dato

Numero di bit usati

Segno (S)

Esponente (E)

Parte frazionaria della mantissa (PF)

Float

32

1 bit

8 bit

23 bit

Double

64

1 bit

11 bit

52 bit


Gli esponenti per i tipi float e double sono rappresentati in eccesso-127 ed eccesso-1023 rispettivamente: ciò vuol dire che al valore effettivo dell’esponente viene sommato il valore 127 (o 1023) e lo si converte in un numero binario intero senza segno su 8 (o 11) bit.
Come esempio determiniamo la rappresentazione a singola precisione di N = -423.
Poiché N è negativo il bit di segno è 1.
In binario il valore 423 diventa 110100111 che in formato IEEE 754 si scrive nella forma 1,10100111 * 28.
L’esponente 8 in eccesso-127 diventa 135, che convertito in binario è 10000111.
Dunque la rappresentazione all’interno del calcolatore sarà:
1 10000111 10100111000000000000000

 

Torna all'indice Generale del corso di Corso di C con Linux di Software Planet