Somma in floating point
Salve ,sono alle prese con il seguente esercizio :
calcolare il valore di (1/10 + 1/5) + 1/6 in F(2,4,-3,4) dove F è l'insieme dei numeri rappresentabili in aritmetica finita in base 2 .
Riporto lo svolgimento
1/10 = 0.11011*2^-3
1/5 = 0.110011*2^-2
1/6=0.101100*2^-2
Risultato : 0.1000*2^0=1/2
Ho capito l'artimetica f.p. e so operare in base 10 ma ho problemi per rappesentare in numeri in aritmetica di macchina ; ci sono diverse codifiche per rappresentare un numero in base 2 , qualche devo scegliere ? come mai ci sono più di 4 cifre per la mantissa?
Grazie in anticipo
calcolare il valore di (1/10 + 1/5) + 1/6 in F(2,4,-3,4) dove F è l'insieme dei numeri rappresentabili in aritmetica finita in base 2 .
Riporto lo svolgimento
1/10 = 0.11011*2^-3
1/5 = 0.110011*2^-2
1/6=0.101100*2^-2
Risultato : 0.1000*2^0=1/2
Ho capito l'artimetica f.p. e so operare in base 10 ma ho problemi per rappesentare in numeri in aritmetica di macchina ; ci sono diverse codifiche per rappresentare un numero in base 2 , qualche devo scegliere ? come mai ci sono più di 4 cifre per la mantissa?
Grazie in anticipo
Risposte
In pratica, qualsiasi processore con FPU supporta in parte o in maniera parziale lo standard IEEE 754 (e le sue versioni successive). Esistono numerosi trucchi e dettagli ma in pratica i numeri sono espressi usando un bit per il segno, un certo numero di bit per l'esponente (espresso in binario senza segno - viene memorizzato il valore uguale all'esponente più un valore che lo renda positivo) e un certo numero di bit per la mantissa che viene memorizzata come un intero senza segno (nel senso che è esattamente la sequenza di bit della mantissa) nel quale viene però data per scontata la presenza del primo 1 (in modo da rappresentare in pratica numeri con una mantissa di un bit più lunga). Questo è in linea di massima come appare un numero floating point sul tuo computer. Ti consiglio di leggere attentamente quella pagina di wikipedia e le risorse in esso contenute. Dai un occhiata in particolare anche a questo (pdf).
Le operazioni si svolgono normalmente facendo calcoli su un numero maggiori di bit per poi arrotondare* alla rappresentazione con un numero minore di bit. Questa cosa è fatta in automatico nel tuo processore. A mano i calcoli non sono diversi da quelli che faresti in decimale, ma usando i numeri binari. In effetti, alcune operazioni sono addirittura più semplici. Anche se come ho già detto nei computer il numero di bit effettivo sul quale vengono fatti i calcoli potrebbe essere superiore di quelli usati per memorizzare il valore (e quindi potrebbe fare i calcoli su un numero maggiori di bit per poi arrotondare) se supponi di fare i calcoli con esattamente un numero di bit per la mantissa e l'esponente devi ricordarti di fare l'arrotondamento tutte le volte. Non ho idea del perché il tuo professore abbia usato quel numero di bit.
* questo comportamento può in realtà essere modificato.
Le operazioni si svolgono normalmente facendo calcoli su un numero maggiori di bit per poi arrotondare* alla rappresentazione con un numero minore di bit. Questa cosa è fatta in automatico nel tuo processore. A mano i calcoli non sono diversi da quelli che faresti in decimale, ma usando i numeri binari. In effetti, alcune operazioni sono addirittura più semplici. Anche se come ho già detto nei computer il numero di bit effettivo sul quale vengono fatti i calcoli potrebbe essere superiore di quelli usati per memorizzare il valore (e quindi potrebbe fare i calcoli su un numero maggiori di bit per poi arrotondare) se supponi di fare i calcoli con esattamente un numero di bit per la mantissa e l'esponente devi ricordarti di fare l'arrotondamento tutte le volte. Non ho idea del perché il tuo professore abbia usato quel numero di bit.
* questo comportamento può in realtà essere modificato.
Grazie della risposta , ho capito come operare però ho ancora un dubbio :
voglio sommare A + B in floating point in singola precisione :
A viene rappresentato nel calcolatore in questo modo
SEGNO ESPONENTE MANTISSA
1 10000010 010101000000000000000000
Mentre b viene rappresentato in questo modo
SEGNO ESPONENTE MANTISSA
0 01111110 111100000000000000000000
quindi per sommarli ho trascritto entrambi i numeri in notazione decimale [ (-1)^sign*1.mantissa*2^exp-127 ] e gli ho sommati ;
c'è un altro modo più spicciolo per fare i conti ?
voglio sommare A + B in floating point in singola precisione :
A viene rappresentato nel calcolatore in questo modo
SEGNO ESPONENTE MANTISSA
1 10000010 010101000000000000000000
Mentre b viene rappresentato in questo modo
SEGNO ESPONENTE MANTISSA
0 01111110 111100000000000000000000
quindi per sommarli ho trascritto entrambi i numeri in notazione decimale [ (-1)^sign*1.mantissa*2^exp-127 ] e gli ho sommati ;
c'è un altro modo più spicciolo per fare i conti ?
Puoi usare il seguente metodo:
1. Portare entrambi i numeri nello stesso esponente (che corrisponde ad un semplice spostamento a destra dei bit della mantissa del numero con esponente minore per la differenza tra i due esponenti).
2. Sommare o sottrarre le mantisse ricordandosi del bit non considerato (in pratica è più comodo portarsi ad un esponente di 1 più grande)
Ti mostro l'idea con i numeri decimali per semplicità. Supponiamo di avere \(-1.074*10^4\) e \(7.239*10^2\). Per prima cosa portiamo entrambi allo stesso esponente spostando le cifre ottenendo \(-1.074*10^4\) e \(0.07239*10^4 \sim 0.072*10^4\). A questo punto faccio la somma ottenendo \(-1.002*10^4\) che è il risultato della somma. Nota che nello spostamento dei bit ho arrotondato il valore per tornare alle 4 cifre che avevo supposto essere usate. In pratica non è detto che vengano usate solo le cifre della rappresentazione per fare i calcoli (nei PC ogni calcolo viene normalmente fatto a 80bit per esempio*). Se i calcoli fossero stati fatti con 6 cifre si sarebbe quindi arrivati a \(-1.00161*10^4\) e quindi allo stesso risultato (ma facendo più calcoli la differenza si vedrebbe). Ti invito a cercare di scrivere un codice nel tuo linguaggio preferito per simulare le operazioni con i floating point. Potrebbe essere un esercizio molto istruttivo.
* Potrebbe non essere sempre valido.
1. Portare entrambi i numeri nello stesso esponente (che corrisponde ad un semplice spostamento a destra dei bit della mantissa del numero con esponente minore per la differenza tra i due esponenti).
2. Sommare o sottrarre le mantisse ricordandosi del bit non considerato (in pratica è più comodo portarsi ad un esponente di 1 più grande)
Ti mostro l'idea con i numeri decimali per semplicità. Supponiamo di avere \(-1.074*10^4\) e \(7.239*10^2\). Per prima cosa portiamo entrambi allo stesso esponente spostando le cifre ottenendo \(-1.074*10^4\) e \(0.07239*10^4 \sim 0.072*10^4\). A questo punto faccio la somma ottenendo \(-1.002*10^4\) che è il risultato della somma. Nota che nello spostamento dei bit ho arrotondato il valore per tornare alle 4 cifre che avevo supposto essere usate. In pratica non è detto che vengano usate solo le cifre della rappresentazione per fare i calcoli (nei PC ogni calcolo viene normalmente fatto a 80bit per esempio*). Se i calcoli fossero stati fatti con 6 cifre si sarebbe quindi arrivati a \(-1.00161*10^4\) e quindi allo stesso risultato (ma facendo più calcoli la differenza si vedrebbe). Ti invito a cercare di scrivere un codice nel tuo linguaggio preferito per simulare le operazioni con i floating point. Potrebbe essere un esercizio molto istruttivo.
* Potrebbe non essere sempre valido.