• Non ci sono risultati.

Capitolo 3

N/A
N/A
Protected

Academic year: 2021

Condividi "Capitolo 3"

Copied!
15
0
0

Testo completo

(1)

Capitolo 3

Aritmetica in virgola mobile

3.1 Le operazioni base dell’aritmetica in virgola mobile

La seguente tabella riassume le operazioni di base per l’aritmetica in virgola mobile:

Numeri in virgola mobile Operazioni aritmetiche

X E X B M X = ⋅ Y E Y B M Y = ⋅ Y x E Y E E X E Y E E X E E B M B M Y X B M B M Y X Y Y X Y Y X ≤    ⋅ − ⋅ = − ⋅ + ⋅ = + − − ) ( ) ( Y X E E Y X M B M Y X ⋅ =( + )⋅ + Y X E E Y X B M M Y X −       =

Esempi (in base 10): 30 10 3 , 0 2 = = X 200 10 2 , 0 3 = = Y 230 10 23 , 0 10 ) 2 , 0 10 3 , 0 ( 2 3 + 3 = 3 = = +YX 170 10 ) 17 , 0 ( 10 ) 2 , 0 10 3 , 0 ( 2 3 3 = 3 = = −YX 5 3 2+ 0,06 10 6000 10 ) 2 , 0 3 , 0 ( ⋅ ⋅ = ⋅ = = ⋅ Y X 1 3 2− 1,5 100,15 10 ) 2 , 0 3 , 0 ( ÷ ⋅ = ⋅ = = ÷ Y X

Tabella 3.1 – Operazioni di base per numeri rappresentati in virgola mobile

Nel caso dell’addizione e della sottrazione, è necessario assicurarsi che entrambi gli operandi abbiano lo stesso valore all’esponente e ciò può richiedere lo scorrimento della virgola su uno degli operandi per raggiungere l’allineamento. La moltiplicazione e la divisione sono più semplici.

(2)

I problemi che possono sorgere eseguendo queste operazioni sono: • Owerflow

dell’esponente :

un esponente positivo supera il massimo valore permesso. In alcuni sistemi questo evento è indicato come +∞ oppure −∞.

• Underflow dell’esponente :

un esponente negativo è più piccolo del minimo valore permesso (ad esempio –200 è più piccolo di –127). Questo significa che il numero è troppo piccolo per essere rappresentato e può essere considerato 0.

• Owerflow della mantissa :

nel processo di allineamento delle mantisse, le cifre possono scorrere oltre l’estremità destra della mantissa. Come si vedrà, sono richiesti dei meccanismi di arrotondamento.

• Underflow della mantissa :

l’addizione di due mantisse dello stesso segno può causare il riporto di un bit oltre la posizione del bit più significativo. Questo inconveniente, come si vedrà in seguito, può essere risolto con un riallineamento.

(3)

Capitolo 3 : Aritmetica in virgola mobile pag. 45

3.2 Addizione e sottrazione

Nell’aritmetica in virgola mobile, l’addizione e la sottrazione sono operazioni più complesse della moltiplicazione e della divisione, a causa della necessità dell’allineamento. L’algoritmo per l’addizione e la sottrazione si divide in quattro fasi basilari:

1. Confronto con lo zero.

2. Allineamento delle mantisse.

3. Addizione o sottrazione delle mantisse. 4. Normalizzazione del risultato.

Un tipico diagramma di flusso è mostrato nella Figura 3.2. Per mettere alla luce le principali funzionalità richieste, segue una spiegazione passo passo dell’algoritmo ipotizzando per i numeri in virgola mobile il formato previsto dallo standard IEEE 754. Per le operazioni di addizione e sottrazione i due operandi devono essere trasferiti nei registri che saranno usati dal sistema di elaborazione e, se il formato per i numeri in virgola mobile include un bit implicito nella mantissa, questo deve essere reso esplicito nel corso dell’operazione. Poiché l’addizione e la sottrazione sono operazioni identiche a meno di un bit segno, il processo inizia cambiando il bit di segno del sottraendo se l’operazione è una sottrazione. Successivamente, se uno degli operandi è zero, l’altro viene restituito come risultato. La fase successiva consiste nel manipolare i numeri in modo da rendere uguali i due esponenti. Per capire la necessità di questo passo, si consideri la seguente addizione decimale :

) 10 456 ( ) 10 123 ( 0 + −2

Chiaramente, non possiamo subito sommare le due mantisse, in quanto le cifre devono essere poste in posizioni equivalenti, ovvero il 4 del secondo numero deve essere allineato con il 3 del primo. Sotto queste condizioni, i

(4)

due esponenti saranno uguali e questa è la condizione matematica per la quale due numeri in questa forma possono essere sommati. Quindi :

0 0 0 2 0) (456 10 ) (123 10 ) (4,56 10 ) 127,56 10 10 123 ( ⋅ + ⋅ − = ⋅ + ⋅ = ⋅

L’allineamento può essere ottenuto facendo scorrere il numero più piccolo verso destra (aumentando il suo esponente) oppure facendo scorrere il numero più grande verso sinistra (diminuendo il suo esponente). Poiché entrambe le operazioni possono causare la perdita di cifre, quello che viene fatto scorrere è il numero più piccolo, in quanto ogni cifra eventualmente persa ha un’importanza relativamente bassa. L’allineamento viene così ottenuto facendo scorrere di un bit verso destra la parte significativa della mantissa incrementando l’esponente, finchè i due esponenti si equivalgono. Se questo processo causa l’azzeramento della mantissa, allora come risultato viene restituito l’altro numero. In questo modo, se due numeri hanno esponenti che differiscono in maniera significativa, il numero più piccolo viene perso. Poi le due mantisse sono aggiunte l’una all’altra tenendo conto dei loro segni e, poiché questi possono differire, il risultato potrebbe essere 0. C’è anche la possibilità che, per una cifra, avvenga un overflow della mantissa: in questo caso, la mantissa del risultato viene fatta scorrere verso destra e l’esponente viene incrementato. Potrebbe avvenire anche un overflow dell’esponente, ma in questo caso viene riferito ciò che è accaduto e l’operazione viene interrotta. Successivamente si ha la normalizzazione del risultato che consiste nel far scorrere le cifre della mantissa verso sinistra, finchè la cifra più significativa non è nulla. Ogni scorrimento causa un decremento dell’esponente e, quindi, potrebbe causare un underflow dell’esponente. Infine, il risultato deve essere arrotondato e quindi restituito. La trattazione sull’arrotondamento verrà fatta dopo la trattazione della moltiplicazione e della divisione.

(5)

Addizione SI X = 0 ? Sottrazione Z ← X NO SI Y = 0 ? Cambia il bit di segno Y Scorri la mantissa a destra Z ← 0 Ritorna Aumenta l’esponente più piccolo Somma le mantisse con segno Mantissa =0 ? Mantissa =0 ? Gli esponenti sono uguali ? Overflow di mantissa? Risultati normalizzati? Scorri a destra la mantissa Scorri a sinistra la mantissa NO Overflow di esponente? Incrementa l’esponente Underflow di esponente? Decrementa l’esponente Metti l’altro numero in Z Ritorna Segnala Underflow Ritorna Ritorna Segnala Overflow NO NO NO NO SI SI NO NO SI SI SI SI SI NO Arrotonda il risultato Ritorna Ritorna Z ← Y

(6)

3.3 Moltiplicazione e divisione

La moltiplicazione e la divisione in virgola mobile sono processi più semplici dell’addizione e della sottrazione. Consideriamo per prima la moltiplicazione illustrata nel diagramma seguente:

Ritorna SI X = 0 ? NO Overflow dell’esponente? Underflow dell’esponente? Normalizza Arrotonda NO Moltiplica le mantisse Ritorna SI Segnala L’underflow SI Segnala l’overflow Y = 0 ? Somma gli esponenti SI NO NO Z ← 0 Sottrai il fattore di polarizzazione Moltiplicazione

(7)

Capitolo 3 : Aritmetica in virgola mobile pag. 49

Se un operando è zero, allora viene restituito come risultato zero. Il passo successivo è sommare i due esponenti: se questi sono memorizzati in forma polarizzata, la loro somma raddoppia il fattore di polarizzazione, che, quindi, deve essere sottratto dalla somma. Se il risultato è un overflow o un underflow di esponente deve essere riferito terminando l’algoritmo. Se l’esponente del prodotto è all’interno dell’intervallo corretto, il passo successivo è moltiplicare le mantisse tenendo conto dei loro segni. La moltiplicazione è eseguita nello stesso modo in cui viene eseguita tra i numeri interi: anche se, in questo caso, si ha a che fare con una rappresentazione modulo e segno, i dettagli sono simili a quelli per la rappresentazione in complemento a due. Il prodotto avrà lunghezza doppia rispetto alle lunghezze del moltiplicano e del moltiplicatore ed i bit extra saranno persi durante l’arrotondamento. Dopo che il prodotto è stato calcolato il risultato è quindi normalizzato ed arrotondato come si è fatto per l’addizione e la sottrazione (si noti che la normalizzazione potrebbe restituire un underflow dell’esponente).

Consideriamo, infine, il diagramma di flusso per la divisione illustrato nella figura 3.3. Ancora una volta, il primo passo è verificare se uno dei due operandi è nullo: se il divisore è zero, il risultato restituito sarà un errore oppure infinito a seconda delle implementazioni, mentre se il dividendo è zero, il risultato restituito sarà zero. Successivamente, l’esponente del divisore viene sottratto dall’esponente del dividendo: questa operazione cancellerà la polarizzazione che, quindi, dovrà essere ristabilita sommando il fattore di polarizzazione. Dopo i test per l’overflow e l’underflow dell’esponente, si passa alla divisione delle mantisse che è seguita dalla normalizzazione e dall’arrotondamento.

(8)

Ritorna X = 0 ? Somma il fattore di polarizzazione Y = 0 ? Overflow dell’esponente? Underflow dell’esponente? Sottrai gli esponenti Z ← 0 SI Normalizza Arrotonda Ritorna Dividi le mantisse Segnala L’underflow Segnala l’overflow SI SI ← Z ∞ SI NO NO NO NO Divisione

(9)

Capitolo 3 : Aritmetica in virgola mobile pag. 51

3.4 Considerazioni sulla precisione

Bit di guardia.

Si è accennato al fatto che, prima di un’operazione in virgola mobile, l’esponente e la mantissa di ogni operando sono caricati in registri del sistema di elaborazione. Nel caso della mantissa, l’ampiezza del registro è quasi sempre maggiore della lunghezza della mantissa più i, bit implicito. Il registro contiene bit addizionali, chiamati di guardia, che sono usati per riempire di zeri la parte destra della mantissa. Il motivo che spinge verso l’uso dei bit di guardia è illustrato nella figura seguente:

= x 1,000...0021 = − y 0,111...1121 = z 0,000...01⋅21 = 1,000...00222

(a) Esempio binario, senza bit di guardia = x 1,000...00 000021 1 = − y 0,111...11 10002 1 2 1000 00 ... 000 , 0 ⋅ = z = 1,000...00 00002−23 (b) Esempio binario, con bit di guardia

Figura 3.4 – Uso dei bit di guardia

Si considerino numeri nel formato IEEE che hanno la mantissa di 24 bit includendo il bit implicito a sinistra della virgola. Due numeri che hanno

valori molto vicini tra di loro sono e Y . Se il

numero più piccolo deve essere sottratto dal più grande, c’è bisogno di uno scorrimento verso destra di una posizione per allineare gli esponenti (si veda la Figura 3.4). Così facendo, Y perde un bit nella mantissa ed il

risultato è ; questa stessa operazione è ripetuta nella Figura 3.4b con

l’aggiunta del bit di guardia. In questo caso, il bit meno significativo non 1 2 00 ... 00 , 1 ⋅ = X =1,11...1120 22 2−

(10)

viene perso a causa dell’allineamento ed il risultato è , c’è una differenza di un fattore 2 dal precedente calcolo.

23 2−

Arrotondamento

Un altro particolare che incide sulla precisione del risultato è l’arrotondamento. Il risultato di un’operazione sulle mantisse è di solito immagazzinato in un registro più grande di questi e, quando il risultato viene riportato in virgola mobile, i bit in eccesso devono essere eliminati. Sono state studiate diverse tecniche per eseguire l’arrotondamento e, per questo, lo standard IEEE elenca quattro approcci alternativi:

• Arrotondamento al più vicino: il risultato è arrotondato al numero rappresentabile più vicino.

• Arrotondamento verso +∞ : il risultato è arrotondato verso l’alto. • Arrotondamento verso −∞ : il risultato è arrotondato verso il basso. • Arrotondamento verso 0 : il risultato viene arrotondato verso lo zero. L’arrotondamento al più vicino è il metodo di arrotondamento di default tra quelli elencati nello standard ed è definito come segue: al numero a precisione illimitata viene assegnato il numero rappresentabile più vicino e, se esistono due valori rappresentabili alla stessa distanza, sarà scelto quello col suo bit meno significativo impostato a zero.

Ad esempio, se i bit in eccesso, oltre i 23 bit che possono essere immagazzinati, sono 10010, allora, poiché il valore di questi ammonta a più della metà del valore dell’ultimo bit rappresentabile, l’arrotondamento corretto è aggiungere 1 all’ultimo bit rappresentabile, avendo così arrotondato al numero rappresentabile successivo. Nel caso in cui i bit extra siano 01111, poiché questi ammontano a meno della metà del valore dell’ultimo bit rappresentabile, l’arrotondamento corretto consiste

(11)

Capitolo 3 : Aritmetica in virgola mobile pag. 53

semplicemente nel rinunciare ai bit in eccesso (troncamento) e l’effetto di questa operazione causa l’arrotondamento verso un numero rappresentabile più piccolo. Lo standard da indicazioni anche per il caso speciale in cui i bit extra sono della forma 10000: in questo caso, il risultato è esattamente a metà tra i due possibili valori rappresentabili. Una possibile tecnica, che è anche la più semplice, sarebbe quella di troncare sempre, ma lo svantaggio di questo approccio è che esso introduce una polarizzazione piccola ma cumulativa all’interno di una sequenza di computazioni. Quello che si richiede è un metodo di depolarizzazione dell’arrotondamento ed una possibile soluzione sarebbe arrotondare verso il basso o verso l’alto sulla base di un numero casuale in maniera tale che, in media, il risultato sarebbe non polarizzato: l’argomento contro questa soluzione è che essa non produce risultati deterministici e prevedibili. La soluzione adottata dallo standard IEEE è forzare il risultato ad essere pari: se il risultato di una computazione è esattamente nel mezzo tra due numeri rappresentabili, il valore è arrotondato verso l’alto se l’ultimo bit rappresentabile è un 1 oppure viene troncato se l’ultimo bit rappresentabile è uno 0.

L’arrotondamento verso 0 è in effetti un semplice troncamento (i bit in eccesso sono ignorati). Questa è sicuramente la tecnica più semplice, ma il risultato è che il modulo del valore troncato è sempre minore o uguale al valore originale, introducendo così nell’operazione una consistente polarizzazione verso lo zero: questa polarizzazione è più seria di quella affrontata precedentemente perché essa condiziona in ogni operazione il cui risultato non presenta bit in eccesso nulli.

(12)

3.5 Lo standard IEEE per l’aritmetica binaria in virgola mobile

Lo standard IEEE 754 va oltre la semplice definizione di un formato e stabilisce specifiche pratiche e procedure, così che l’aritmetica in virgola mobile possa produrre risultati uniformi, prevedibili ed indipendenti dalla piattaforma hardware. Un aspetto di questo, l’arrotondamento, è gia stato discusso, ora ci occuperemo di: l’infinito, i NaN ( Not a Number) ed i numeri denormalizzati.

Infinito

L’aritmetica dell’infinito è trattata come un caso ristretto dell’aritmetica reale, dando ai valori infiniti la seguente interpretazione:

− < (tutti i numeri finiti) < +∞

Con l’eccezione dei casi speciali discussi in seguito, ogni operazione aritmetica che coinvolge l’infinito produce gli ovvi risultati della tabella 3.2 di seguito riportata.

( )

+∞ =+∞ + 7 7÷

( )

+∞ =+0

( )

+∞ =−∞ − 7 7÷

( )

−∞ =−0

( )

−∞ =−∞ + 7

( ) ( )

+∞ + +∞ =+∞

( )

−∞ =+∞ − 7

( ) ( )

−∞ + −∞ =−∞

( )

+∞ =+∞ ⋅ 7

( ) ( )

−∞ − +∞ =−∞

( )

−∞ =−∞ ⋅ 7

( )

+∞ −(−∞)=+∞

(13)

Capitolo 3 : Aritmetica in virgola mobile pag. 55

NaN silenziosi e NaN di segnalazione

Un NaN è un’entità simbolica codificata nel formato in virgola mobile, che può essere di due tipi: NaN di segnalazione e NaN silenzioso. Un NaN di segnalazione indica un’operazione non valida ogni volta che esso compare come un operando: tali NaN offrono valori per le variabili non inizializzate e miglioramenti di tipo aritmetico che non sono oggetto dello standard. Un NaN silenzioso si propaga attraverso quasi tutte le operazioni aritmetiche senza segnalare eccezioni e la tabella 3.3 elenca le operazioni che producono un NaN silenzioso.

Operazione NaN silenzioso prodotto da

Qualsiasi Qualsiasi operazione su

un NaN di segnalazione Addizione e sottrazione Sottrazione di infiniti:

( ) (

+∞ − +∞

)

( ) (

−∞ − −∞

)

( ) (

−∞ + +∞

)

( )

+∞ +(−∞) Moltiplicazione ∞0⋅ Divisone 0 0 oppure ∞ ∞

Resto x mod 0 oppure mod y ∞

Radice quadrata x dove x<0

Tabella 3.3 – Operazioni che producono un NaN silenzioso

Si osservi che entrambi i tipi di NaN hanno lo stesso formato generale : un esponente di tutti uno ed una mantissa non nulla. La sequenza di bit reale

(14)

della mantissa non nulla dipende dall’implementazione ed i valori della mantissa possono essere usati per distinguere i NaN silenziosi dai NaN di segnalazione e per specificare particolari condizioni di eccezione.

Numeri denormalizzati

I numeri denormalizzati sono inclusi nello standard IEEE 754 per manipolare anche i casi in cui si verifica un underflow di esponente: infatti, quando l’esponente del risultato diventa troppo piccolo (un esponente negativo con un modulo troppo grande), il risultato viene denormalizzato con uno scorrimento verso destra dei bit della mantissa ed incrementando di uno il valore dell’esponente per ogni scorrimento fatto finchè il valore dell’esponente ricade in un intervallo rappresentabile. La Figura 3.4 mostra gli effetti dell’addizione di numeri denormalizzati: i numeri rappresentabili possono essere raggruppati in intervalli della forma

[

2n,2n+1

]

, all’interno dei quali la parte del numero che rappresenta l’esponente resta costante mentre la mantissa varia, producendo una spaziatura uniforme di numeri rappresentabili all’interno dell’intervallo. Man mano che ci si avvicina allo zero, ogni intervallo successivo ha una larghezza che è la metà di quella dell’intervallo precedente, ma contiene la stessa quantità di numeri rappresentabili. Quindi la densità dei numeri rappresentabili cresce con l’avvicinarsi allo zero. Tuttavia, se vengono usati soltanto numeri normalizzati, c’è un divario tra il più piccolo numero normalizzato e lo

zero: nel caso del formato a 32 bit IEEE 754, ci sono numeri

rappresentabili in ogni intervallo ed il numero positivo rappresentabile più

piccolo è . Con l’utilizzo dei numeri denormalizzati sono aggiunti altri

numeri nell’intervallo tra 0 e . Ci si riferisce all’uso dei numeri

denormalizzati come underflow graduale. Senza i numeri denormalizzati, il divario tra il numero rappresentabile più piccolo non nullo e lo zero è molto più ampio del divario tra il numero rappresentabile più piccolo non nullo ed

23 2 126 2− 23 2 2−126

(15)

Capitolo 3 : Aritmetica in virgola mobile pag. 57

il numero più grande successivo. L’underflow graduale colma questo divario e riduce l’impatto dell’underflow dell’esponente ad un livello confrontabile con l’arrotondamento tra numeri normalizzati.

Divario

0 2−126 2−125 2−124 2−123 (a) Formato a 32 bit senza numeri denormalizzati

Spaziatura uniforme

0 2−126 2−125 2−124 2−123 (b) Formato a 32 bit con numeri denormalizzati

Figura 3.5 – L’effetto dei numeri denormalizzati nello standard IEEE 754

Bibliografia

[3.1] William Stallings, “Architettura e organizzazione dei calcolatori” Per tutto il capitolo.

Riferimenti

Documenti correlati

COMPLETA LE MACCHINE DELLE

Sommando queste due parti ottieni un’area maggiore o minore della metà di quella

Immaginiamo di avere la nostra solita pizza divisa in 4 parti congruenti.. Se ne mangio prima un quarto e poi ancora due quarti in totale ne ho mangiato i

Esercizi matematica Data:. Esercizi sulla

Due caraffe identiche contengono dell’acqua, la prima per i 4/5 e la seconda per i 2/3 della capacità totale.. Franco usa la seconda caraffa per riempire fino all’orlo la

Se del caso prima di eseguire il calcolo conviene ridurre le frazioni ai minimi termini3. Di solito si usa ridurre il risultato ai

Esercizio tratto dal libro “Atolli matematici II, Casagrande Editore”6. Abbiamo appreso l’addizione e la sottrazione coi numeri

La nonna di Pino gioca in squadra con il marito , che ha totalizzato 60 punti , mentre Silvana gioca in coppia con la suocera , che ha raggiunto quota 40 punti.. Alla fine