Salta al contenuto
Note per Studenti Esercizio 28 · virgola mobile, conversioni e formati ridotti

Esercizio 28virgola mobile, conversioni e formati ridotti

Esame
In questa pagina 9

Testo (esempi di compito e di compitino di Architettura degli Elaboratori, UniPD, a.a. 2010-11, 2011-12, 2014-15 e 2015-16: quesito 2 a risposta multipla e due esercizi sulla virgola mobile). Teoria: Numeri in virgola mobile IEEE 754Virgola fissa e virgola mobile; formato IEEE 754 a 32 e 64 bit (segno, esponente in eccesso 127, mantissa con 1 implicito); conversioni svolte nei due versi; valori speciali, denormalizzati, intervallo, precisione e arrotondamento.Numeri in virgola mobile IEEE 754 →.

  1. Convertire il numero −30,375-30{,}375 in formato a virgola mobile IEEE 754 a precisione singola.
  2. Che numero rappresenta la configurazione 0100 0110 0100 0110 0000 0000 0000 0000 in formato IEEE 754 a precisione singola?
  3. Si consideri la rappresentazione in virgola mobile a precisione singola (IEEE 754) 1100 0000 1110 1010 0000 0000 0000 0000. Il numero rappresentato è: a) −7,3125-7{,}3125; b) −1,828125-1{,}828125; c) 1,8281251{,}828125; d) 7,31257{,}3125; e) nessuna delle precedenti.
  4. Stessa domanda per 0011 1110 0011 1000 0000 0000 0000 0000: a) 1,43751{,}4375; b) −0,1796875-0{,}1796875; c) 0,17968750{,}1796875; d) −1,4375-1{,}4375; e) nessuna.
  5. Si consideri la rappresentazione in virgola mobile che usa 3 bit per l'esponente e 4 bit per la mantissa (più il bit di segno). Il numero −7,3-7{,}3 viene rappresentato dalla sequenza: a) 11011101; b) 10101101; c) 11101101; d) 11101010; e) nessuna.
  6. Con 4 bit per l'esponente e 11 bit per la mantissa il numero −41,125-41{,}125 è rappresentato da: a) 1110001001001000; b) 1010101001001000; c) 1010010010001100; d) 1010010010000101; e) nessuna.

Formato

Un numero normalizzato è (−1)s⋅1,f⋅2 E−bias(-1)^s \cdot 1{,}f \cdot 2^{\,E - \text{bias}} con bias=2k−1−1\text{bias} = 2^{k-1} - 1 (kk bit di esponente) e bit nascosto 11 davanti alla frazione. Singola precisione: 1 bit di segno, 8 di esponente (bias 127127), 23 di frazione. Nei formati ridotti dei quesiti 5 e 6 si usa la stessa regola con k=3k = 3 (bias 33) e k=4k = 4 (bias 77); è l'unica interpretazione che porta a una delle opzioni elencate.

Codificare xx:

  1. segno: s=1s = 1 se x<0x < 0;
  2. scrivere ∣x∣|x| in binario e normalizzare: 1,f×2e1{,}f \times 2^e;
  3. esponente memorizzato E=e+biasE = e + \text{bias}, in binario su kk bit;
  4. frazione: i bit dopo la virgola, riempiti con zeri a destra o troncati a mm bit.

Decodificare: l'inverso. Vedi gli esempi in Numeri in virgola mobile IEEE 754Virgola fissa e virgola mobile; formato IEEE 754 a 32 e 64 bit (segno, esponente in eccesso 127, mantissa con 1 implicito); conversioni svolte nei due versi; valori speciali, denormalizzati, intervallo, precisione e arrotondamento.Numeri in virgola mobile IEEE 754 →.

1. −30,375-30{,}375 in singola precisione

  • Segno s=1s = 1.
  • 30=11110230 = 11110_2; 0,375=0,01120{,}375 = 0{,}011_2 (0,25+0,1250{,}25 + 0{,}125). Quindi 30,375=11110,011230{,}375 = 11110{,}011_2.
  • Normalizzando: 11110,0112=1,11100112×2411110{,}011_2 = 1{,}1110011_2 \times 2^4.
  • Esponente memorizzato: 4+127=131=1000 001124 + 127 = 131 = 1000\,0011_2.
  • Frazione: 1110011 seguita da 1616 zeri (23 bit totali): 11100110000000000000000.

−30,375=1 10000011 11100110000000000000000=C1F3000016.-30{,}375 = \texttt{1\ 10000011\ 11100110000000000000000} = \texttt{C1F30000}_{16}.

2. 0 10001100 10001100000000000000000

  • Segno 00: positivo.
  • Esponente 100011002=14010001100_2 = 140; 140−127=13140 - 127 = 13.
  • Frazione 1000110...: 0,10001102=2−1+2−5+2−6=0,5+0,03125+0,015625=0,5468750{,}1000110_2 = 2^{-1} + 2^{-5} + 2^{-6} = 0{,}5 + 0{,}03125 + 0{,}015625 = 0{,}546875; con il bit nascosto 1,5468751{,}546875.

+1,546875×213=1,546875×8192=12 672.+1{,}546875 \times 2^{13} = 1{,}546875 \times 8192 = \mathbf{12\,672}.

3. 1 10000001 11010100000000000000000

  • Segno 11: negativo; esponente 100000012=12910000001_2 = 129 → 129−127=2129 - 127 = 2.
  • Frazione 1101010...: 2−1+2−2+2−4+2−6=0,5+0,25+0,0625+0,015625=0,8281252^{-1} + 2^{-2} + 2^{-4} + 2^{-6} = 0{,}5 + 0{,}25 + 0{,}0625 + 0{,}015625 = 0{,}828125; con il bit nascosto 1,8281251{,}828125.

−1,828125×22=−7,3125-1{,}828125 \times 2^2 = -7{,}3125 → risposta a. (−1,828125-1{,}828125 è la mantissa senza l'esponente: errore di chi dimentica 222^2.)

4. 0 01111100 01110000000000000000000

  • Segno 00; esponente 011111002=12401111100_2 = 124 → 124−127=−3124 - 127 = -3.
  • Frazione 0111: 2−2+2−3+2−4=0,43752^{-2} + 2^{-3} + 2^{-4} = 0{,}4375; con il bit nascosto 1,43751{,}4375.

1,4375×2−3=1,4375/8=0,17968751{,}4375 \times 2^{-3} = 1{,}4375 / 8 = 0{,}1796875 → risposta c.

5. Formato 1 + 3 + 4 bit: −7,3-7{,}3

  • Segno 11. 7,3=111,0100110011…2=1,110100110011…2×227{,}3 = 111{,}0100110011\ldots_2 = 1{,}110100110011\ldots_2 \times 2^2.
  • Esponente memorizzato: 2+3=5=10122 + 3 = 5 = 101_2.
  • Frazione: 4 bit: 1101 (i bit successivi, 00110011..., si troncano).

1 101 1101=11011101⇒risposta a.\texttt{1\ 101\ 1101} = \texttt{11011101} \quad \Rightarrow \text{risposta a.}

Il numero realmente rappresentato è −1,11012×22=−(1+0,8125)×4=−7,25-1{,}1101_2 \times 2^2 = -(1 + 0{,}8125) \times 4 = -7{,}25: la rappresentazione di −7,3-7{,}3 è approssimata (errore 0,050{,}05): con 4 bit di frazione i numeri vicini a 7 distano 2−4⋅22=0,252^{-4} \cdot 2^2 = 0{,}25.

6. Formato 1 + 4 + 11 bit: −41,125-41{,}125

  • Segno 11. 41=101001241 = 101001_2, 0,125=0,00120{,}125 = 0{,}001_2: 41,125=101001,0012=1,010010012×2541{,}125 = 101001{,}001_2 = 1{,}01001001_2 \times 2^5.
  • Esponente memorizzato: bias 77: 5+7=12=110025 + 7 = 12 = 1100_2.
  • Frazione, 11 bit: 01001001 completata con tre zeri: 01001001000.

1 1100 01001001000=1110001001001000⇒risposta a.\texttt{1\ 1100\ 01001001000} = \texttt{1110001001001000} \Rightarrow \text{risposta a.}

Questo numero è esatto: 41,12541{,}125 ha solo 8 bit dopo la virgola nella forma normalizzata, che stanno negli 11 bit di frazione.

Verifica con un programma

python
import struct
from fractions import Fraction

def codifica(x, bit_esp, bit_man):
    """x -> bit (segno, esponente con bias 2^(k-1)-1, 1.f troncata a bit_man bit); solo numeri normalizzati."""
    bias = 2 ** (bit_esp - 1) - 1
    s = "1" if x < 0 else "0"
    x = abs(Fraction(x))
    e = 0
    while x >= 2:
        x /= 2; e += 1
    while x < 1:
        x *= 2; e -= 1
    man = int((x - 1) * 2 ** bit_man)                 # troncamento
    return s + format(e + bias, f"0{bit_esp}b") + format(man, f"0{bit_man}b")

def decodifica(bits, bit_esp, bit_man):
    bias = 2 ** (bit_esp - 1) - 1
    segno = -1 if bits[0] == "1" else 1
    E = int(bits[1:1 + bit_esp], 2)
    m = int(bits[1 + bit_esp:], 2)
    return segno * (1 + Fraction(m, 2 ** bit_man)) * Fraction(2) ** (E - bias)

print(codifica(Fraction(-30375, 1000), 8, 23))                    # 11000001111100110000000000000000
print(hex(struct.unpack(">I", struct.pack(">f", -30.375))[0]))    # 0xc1f30000: il controllo con il float vero
print(float(decodifica("01000110010001100000000000000000", 8, 23)))   # 12672.0
print(float(decodifica("11000000111010100000000000000000", 8, 23)))   # -7.3125
print(float(decodifica("00111110001110000000000000000000", 8, 23)))   # 0.1796875
b5 = codifica(Fraction(-73, 10), 3, 4)
print(b5, float(decodifica(b5, 3, 4)))                            # 11011101 -7.25
print(codifica(Fraction(-41125, 1000), 4, 11))                    # 1110001001001000

Errori comuni

  • Dimenticare il bit nascosto (usare 0,f0{,}f invece di 1,f1{,}f).
  • Non sottrarre il bias (o sottrarre 128, 255): per 8 bit il bias è 127127.
  • Dimenticare di moltiplicare per 2E−bias2^{E - \text{bias}} e dare come risposta la mantissa (−1,828125-1{,}828125).
  • Normalizzare male: 30,375=1,1110011×2430{,}375 = 1{,}1110011 \times 2^4 (si sposta la virgola di 4 posti).
  • Usare il bias di 127 anche nei formati ridotti: con kk bit il bias è 2k−1−12^{k-1} - 1.
  • Credere che −7,3-7{,}3 sia memorizzato esattamente: con pochi bit si rappresenta solo un numero vicino.

Versione ripasso

Esempi di compito e compitino (UniPD, a.a. 2010-11, 2011-12, 2014-15, 2015-16): virgola mobile IEEE 754. Teoria: Numeri in virgola mobile IEEE 754Virgola fissa e virgola mobile; formato IEEE 754 a 32 e 64 bit (segno, esponente in eccesso 127, mantissa con 1 implicito); conversioni svolte nei due versi; valori speciali, denormalizzati, intervallo, precisione e arrotondamento.Numeri in virgola mobile IEEE 754 →.

Formato: (−1)s⋅1,f⋅2E−bias(-1)^s \cdot 1{,}f \cdot 2^{E - \text{bias}}, bias 2k−1−12^{k-1} - 1 (127127 per 8 bit, 33 per 3 bit, 77 per 4 bit); bit nascosto 11.

Codificare: segno; ∣x∣|x| in binario normalizzato 1,f×2e1{,}f \times 2^e; E=e+biasE = e + \text{bias}; frazione troncata a mm bit.

  • −30,375=−1,11100112×24-30{,}375 = -1{,}1110011_2 \times 2^4 → 1 10000011 11100110000000000000000 (C1F3000016\text{C1F30000}_{16}).
  • 0 10001100 1000110... → 140−127=13140 - 127 = 13, 1,546875×213=12 6721{,}546875 \times 2^{13} = 12\,672.
  • 1 10000001 1101010... → −1,828125×22=−7,3125-1{,}828125 \times 2^2 = -7{,}3125 (risposta a).
  • 0 01111100 0111... → 1,4375×2−3=0,17968751{,}4375 \times 2^{-3} = 0{,}1796875 (risposta c).
  • Formato 1+3+4: −7,3=−1,1101…×22-7{,}3 = -1{,}1101\ldots \times 2^2, E=5=101E = 5 = 101 → 11011101 (valore effettivo −7,25-7{,}25).
  • Formato 1+4+11: −41,125=−1,01001001×25-41{,}125 = -1{,}01001001 \times 2^5, E=12=1100E = 12 = 1100 → 1110001001001000 (esatto).

Errori comuni: bit nascosto dimenticato; bias non sottratto; 2E−bias2^{E-\text{bias}} dimenticato; normalizzazione sbagliata; bias 127 nei formati ridotti.

Teoria collegata