[go: up one dir, main page]

Lo standard IEEE per il calcolo in virgola mobile (IEEE 754) (ufficialmente: IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std 754-1985) o anche IEC 60559:1989, Binary floating-point arithmetic for microprocessor systems) è lo standard più diffuso nel campo del calcolo automatico. Questo standard definisce il formato per la rappresentazione dei numeri in virgola mobile (compreso ±0 e i numeri denormalizzati; gli infiniti e i NaN, "not a number"), e un set di operazioni effettuabili su questi. Specifica inoltre quattro metodi di arrotondamento e ne descrive cinque eccezioni.

Esistono in questo standard quattro formati per i numeri in virgola mobile: a precisione singola (32 bit), precisione doppia (64 bit), precisione singola estesa (≥ 43 bit), raramente usato, e precisione doppia estesa (≥ 79 bit), supportata solitamente con 80 bit. La precisione singola è il minimo richiesto dallo standard, gli altri sono opzionali.

Struttura di un numero in virgola mobile

modifica

Un numero in virgola mobile, secondo lo standard IEEE è rappresentato su parole di 32, 64 o 128 bit divisi in tre parti:

in questo ordine. Gli n bit di una stringa sono indicizzati in modo decrescente con numeri interi da n-1 a 0. In un numero in questo standard, l'importanza del bit decresce col suo indice.

Numeri a 32bit

modifica

Di seguito è rappresentato un numero in una stringa di 32 bit:

 1     8               23               lunghezza in bit
+-+--------+-----------------------+
|S|  Esp.  |       Mantissa        |
+-+--------+-----------------------+
31 30      22                      0    indice dei bit

Il valore del numero rappresentato è calcolabile come:

 

Il campo s specifica il segno del numero: 0 per i numeri positivi, 1 per i numeri negativi. Il campo e contiene l'esponente del numero in forma intera. Essendo costituito da 8 bit, permette di rappresentare 256 valori. I valori 0 e 255 vengono riservati per funzioni speciali (descritte in seguito); gli altri permettono di rappresentare 254 valori per i numeri in forma normale, compresi tra -126 e 127, dato che questo campo deve poter rappresentare sia numeri enormi che minimi; tuttavia, adoperando il metodo usato per la rappresentazione del segno dei numeri interi, si creerebbero problemi per il confronto tra numeri. Per risolvere questo problema, il campo è rappresentato in eccesso k detto bias (che è pari a 2^(n-1)-1 con n il numero di bit dell'esponente), per cui:

e = E + k

e reciprocamente

E = e - k

In questo standard, per i numeri a precisione singola, il bias è uguale a 127. In questa rappresentazione (chiamata polarizzazione), i valori dell'esponente compresi tra -126 e 127 assumono invece, nella scrittura del byte, i valori compresi tra 1 e 254, eliminando la necessità di un bit riservato al segno. In fase di decodifica del numero, il bias viene nuovamente sottratto per recuperare il valore originale.

[-126,...,0,...,127] --> [-126+127,...,0+127,...,127+127] --> [1,...,127,...,254] --> [00000001,...,01111111,...,11111110]

I valori assunti dall'esponente e e dalla mantissa m determinano l'appartenenza del numero ad una di queste categorie:

  • zeri;
  • numeri in forma normale;
  • numeri in forma denormalizzata;
  • infiniti;
  • NaN (not a number).

L'esponente distingue i numeri in modo primario, la mantissa in modo secondario.

Categoria Esp. Mantissa
Zeri 0 0
Numeri denormalizzati 0 non zero
Numeri normalizzati 1-254 qualunque
Infiniti 255 0
Nan (not a number) 255 non zero

Il campo m è una stringa di bit che rappresenta la sequenza di cifre dopo la virgola. Tutte le mantisse sono normalizzate in modo che il numero prima della virgola sia 1, per cui per un dato m il valore matematico corrispondente è

M=1,m

In pratica, la mantissa è costituita dal numero binario 1, preceduto dalla virgola e dalla parte intera del numero rappresentato, in forma binaria; la mantissa risulta così artificialmente compresa tra 1 e 2. Quando un numero è normalizzato, come risulta dal suo esponente, il primo bit della mantissa, pari a 1, viene omesso per convenienza: viene quindi chiamato bit nascosto, o bit implicito.

Con questo sistema di rappresentazione, si hanno due zeri (+0 e −0) e due infiniti (+∞ e −∞) a seconda del valore del primo bit. Inoltre i numeri subnormali possono avere un segno e una mantissa, utili però solo per l'analisi.

Questo sistema di rappresentazione permette di avere una precisione relativa x quasi costante per tutti i valori rappresentabili. Infatti

 

Facciamo un semplice esempio: codifichiamo il numero −118.5 nel sistema IEEE 754.

Dobbiamo determinarne il segno, l'esponente e la mantissa.

Poiché è un numero negativo, il primo bit è "1".

Poi scriviamo il numero in forma binaria: 1110110,1.

Successivamente spostiamo la virgola verso sinistra, lasciando solo un 1 alla sua sinistra:  .

La mantissa è la parte a destra della virgola, riempita con zeri a destra fino a riempire i 23 bit: 11011010000000000000000.

L'esponente è pari a 6, ma dobbiamo convertirlo in forma binaria e adattarlo allo standard. Per la precisione singola, dobbiamo aggiungere 127. Quindi 6 + 127 = 133. In forma binaria: 10000101.

Assemblando il tutto:

 1     8               23
+-+--------+-----------------------+
|S|  Esp   |  Mantissa             |
|1|10000101|11011010000000000000000|
+-+--------+-----------------------+
31 30      22                      0

Numeri da 64 bit

modifica

La precisione a 64 bit è doppia rispetto a quella da 32 bit assunta come base dallo standard:

 1     11                                52
+-+-----------+----------------------------------------------------+
|S|  Esp      |  Mantissa                                          |
+-+-----------+----------------------------------------------------+
63 62        51                                                    0

I NaN e gli infiniti sono rappresentati con esponenti formati da una serie di 1 (pari a 2047).

Per i numeri normalizzati il bias è pari a 1023 (quindi e = E + 1023). Per i numeri denormalizzati l'esponente è −1022 (il minimo esponente per un numero normalizzato). Come prima, sia gli infiniti che gli zeri possono essere rappresentati con entrambi i segni.

La precisione decimale è di circa 16 cifre decimali.

Numeri a 128 bit

modifica

La norma regolamenta infine i numeri da 128 bit, che permettono una precisione quadrupla rispetto ai numeri da 32 bit assunti come base dallo standard:

 1     15                                                              112
+-+---------------+---------------------------------------------------------------------------------+
|S|  Esp          |  Mantissa                                                                       |
+-+---------------+---------------------------------------------------------------------------------+

Il numero di bits dedicati all'esponente sale da 11 a 15 e quelli per la mantissa a 112.

La precisione totale sale a circa 34 cifre decimali.

Il bias dell'esponente è pari a 16383 (quindi e = E − 16383).

Revisione dello standard

modifica

Lo standard è attualmente sotto revisione (IEEE 754r).

Conversione da decimale in formato P754

modifica

Esistono innumerevoli modi per rappresentare numeri in virgola mobile ma il sistema più utilizzato è lo standard IEEE P754; questo metodo comporta l'utilizzo della notazione scientifica, in cui ogni numero è identificato dal segno, da una mantissa (1,xxxxx) e dall'esponente ( ). La procedura standard per la conversione da numero decimale a numero binario P754 è la seguente:

  1. Prima di tutto il numero, in valore assoluto, va convertito in binario.
  2. Il numero va poi diviso (o moltiplicato) per 2 fino a ottenere una forma del tipo 1,xxxxxx.
  3. Di questo numero viene eliminato l'1 iniziale (per risparmiare memoria)
  4. Il numero di volte per cui il numero è stato diviso (o moltiplicato, e nel qual caso il valore sarà negativo) per 2 rappresenta l'esponente: questo valore (decimale) va espresso in eccesso 127, ovvero è necessario sommare 127 e convertire il numero risultante in binario. Nel caso di rappresentazione a precisione doppia (v. definizione seguente) il valore dell'esponente viene espresso in eccesso 1023.

A questo punto abbiamo raccolto tutti i dati necessari per memorizzare il numero: in base al numero di bit che abbiamo a disposizione possiamo utilizzare tre formati: il formato a precisione singola (32 bit), il formato a precisione doppia (64 bit) e il formato a precisione quadrupla (128 bit).

  1. Nel primo caso possiamo scrivere il valore utilizzando 1 bit per il segno, 8 bit per l'esponente e 23 bit per la mantissa.
  2. Nel secondo caso servirà 1 bit per il segno, 11 bit per l'esponente e 52 per la mantissa.
  3. Nel terzo caso servirà 1 bit per il segno, 15 bit per l'esponente e 112 per la mantissa.

Per esempio, convertiamo il valore   in binario P754 single:

  1. Convertiamo prima di tutto il numero:   per la parte intera e  . Quindi il numero definitivo è   (segno escluso).
  2. Dividiamo poi il numero per 2 per ottenere la seguente notazione:  
  3. La mantissa diventa, quindi: 1100101.
  4. Per esprimere l'esponente in eccesso 127, infine:  

Il numero, alla fine, sarà espresso nel formato:

1 10000010 11001010000000000000000

Esempio di calcolo per numeri a precisione singola (32 bit)

modifica

Prendiamo per esempio il numero negativo frazionario:

-5,828125

Trasformiamo in binario la parte intera:

5:2=2 R=1
2:2=1 R=0
1:2=0 R=1
5(10) = 101(2)

Trasformiamo ora la parte decimale in binario:

0,828125*2=1,65625 U=1
0,65625 *2=1,3125  U=1
0,3125  *2=0,625   U=0
0,625   *2=1,25    U=1
0,25    *2=0,5     U=0
0,5     *2=1       U=1
0,828125(10) = 110101(2)

Uniamo ora le due parti:

101,110101

Spostiamo la virgola due posizioni verso sinistra riscrivendo in questo modo il risultato:

1,01110101*2^2

Otteniamo quindi la parte iniziale della nostra mantissa 01110101, ed avendo spostato verso sinistra la virgola di due posizioni per ottenere lo stesso numero dobbiamo moltiplicare 2 al quadrato.

A questo punto ricaviamo l'esponente sommando 2 al bias:

2+127=129

Trasformiamo questo numero in binario:

129:2=64 R=1
 64:2=32 R=0
 32:2=16 R=0
 16:2= 8 R=0
  8:2= 4 R=0
  4:2= 2 R=0
  2:2= 1 R=0
  1:2= 0 R=1
129(10)=10000001(2)

Abbiamo così ottenuto il nostro numero in floating point ricordandoci di mettere ad 1 il bit del segno in quanto siamo partiti da un numero negativo:

-5,828125(10)=1|1000 0001|0111 0101 0000 0000 0000 000(2)

Se vogliamo ora esprimere in esadecimale il numero trovato (senza tener conto dell'eventuale formato Little Endian che modificherebbe la disposizione dei byte) non ci resta che suddividerlo a gruppi di quattro e trovare i valori esadecimali corrispondenti:

1100 0000 1011 1010 1000 0000 0000 0000
 C    0    B    A    8    0    0    0

In base sedici il nostro numero in floating point standard IEEE 754 sarà:

C0BA8000

Voci correlate

modifica

Altri progetti

modifica

Collegamenti esterni

modifica