Virgola fissa - formati n.m e normalizzazione
In questa pagina 5
L'aritmetica a virgola fissa (fixed pointnumeri con la virgola in una posizione stabilita una volta per tutte dal programmatore) è quella usata nella maggior parte dei µC e in molti DSP. In sostanza è l'aritmetica degli interi con segno (Numeri binari e complemento a dueI processori lavorano con un numero fisso di bit $n$. I naturali vanno da $0$ a $2^n-1$; per i negativi si usa il complemento a due: $C_2(N)=2^n-N=\overline N+1$ (si invertono tutti i bit e si somma 1). Con $n$ bit rappresenta $-2^{n-1}\le N\le2^{n-1}-1$, ha un solo zero e unifica somma e sottrazione. Quando il risultato esce dall'intervallo c'è overflow; gli overflow intermedi si compensano se il risultato finale è rappresentabile. La lunghezza di parola non è l'accuratezza.Numeri binari e complemento a due →), più un fattore di normalizzazionecostante 2 elevato a m per cui si moltiplica il valore reale prima di arrotondarlo a intero deciso dal programmatore e mai scritto nel dato. Fissare la normalizzazionescelta del fattore di scala, cioè di dove sta la virgola, per un dato significa fissare l'intervallo dei valori rappresentabili. Senza conoscerla è impossibile decodificare un numero.
Il formato n.m
Si indica con n.m una parola in cui:
- è il numero di bit della parte frazionaria (la virgola è posti a destra del bit meno significativo);
- è il numero di bit della parte intera; se il numero è con segno (S), in è incluso il bit di segno; se è senza segno (U), tutti gli bit sono di valore.
Su una parola di bit si ha . Il valore del codice intero (letto come naturale per U, come complemento a 2codifica dei numeri con segno: il negativo di N su n bit è 2 elevato a n meno N per S) è
- Formato U: .
- Formato S: .
- Risoluzione (passo tra due valori vicini, il peso del bit meno significativo, LSBLeast Significant Bit: il bit meno significativo; per un valore normalizzato pesa ): . L'errore massimo di arrotondamentosostituzione del valore con il più vicino rappresentabile è metà passo: .
Tabella per (la scelta di è un compromesso tra intervallo e risoluzioneil più piccolo passo tra due valori rappresentabili consecutivi):
| Formato | Intervallo | Risoluzione |
|---|---|---|
| 0.16 U | ||
| 1.15 U | ||
| 2.14 U | ||
| 4.12 U | ||
| 8.8 U | ||
| 1.15 S (Q15) | ||
| 2.14 S | ||
| 3.13 S | ||
| 8.8 S | ||
| 16.0 S | (interi) |
Il caso (U) o (S) si chiama rappresentazione frazionariaformato in cui i numeri sono frazioni minori di 1 in modulo o Qnformato frazionario in cui la virgola è subito dopo il bit di segno: Q15 coincide con 1.15, Q7 con 1.7: i numeri sono frazioni in e il massimo positivo è su 16 bit. Per un intero puro si ha (virgola a destra dell'LSB). Per le parole a 8 bit Q7 vuol dire 1.7, per 16 bit Q15 vuol dire 1.15.
Decodificare: dal codice esadecimale al decimale
Procedura: (1) leggere il codice come intero (per S, se il bit più alto è 1 sottrarre ); (2) dividere per .
Esempi su 16 bit.
- in 3.13 U: .
- in 1.15 S: il bit più alto è 1, quindi e .
- in 2.14 U: .
- in 9.7 S: , .
- Lo stesso codice vale in 3.13 S: ; in 3.13 U: ; in 5.11 S: ; in 5.11 U: . Cambiando il formato cambia tutto.
- in 8.8 S: , .
Errori da evitare quando si somma e si moltiplica
Due insidie sempre presenti:
- Somma: i due addendi devono avere lo stesso fattore di scala. Il processore non allinea da solo le virgole. Esempio: (formato 2.4: ) più () dà , corretto solo perché le virgole coincidono.
- Prodotto: moltiplicando due numeri e si ottiene un intero che ha bit frazionari: il fattore di scala del prodotto è il prodotto dei fattori di scala (per questo, dopo il prodotto, serve un riallineamentospostamento (shift) del risultato per riportarlo allo stesso fattore di scala degli altri dati). Esempio: ; interpretato con 4 bit frazionari vale (sbagliato); con bit frazionari vale (corretto).
Questi due punti, con il resto delle operazioni, sono in Operazioni in virgola fissa - somma, prodotto e riallineamentoIn virgola fissa il processore opera sugli interi e non sa dov'è la virgola: tocca al programmatore. Regola 1: si sommano solo dati con lo stesso formato (stesso $m$). Regola 2: il prodotto di $n_1.m_1$ per $n_2.m_2$ ha $m_1+m_2$ bit frazionari e il doppio dei bit: va riallineato con uno shift a destra di $m_2$ posizioni (per riportarlo a $m_1$) o preso dalla parte alta. Con la normalizzazione frazionaria $1.15$ il prodotto è $2.30$ e basta uno shift a sinistra di 1 prima di prendere la parte alta. I fattori di scala si scelgono per evitare overflow e perdita di risoluzione.Operazioni in virgola fissa - somma, prodotto e riallineamento →. Come si sceglie il formato e si calcola l'errore è in Rappresentare un valore reale in virgola fissa - formato ottimo ed errorePer rappresentare un reale $x$ su $W$ bit a virgola fissa si sceglie il formato che minimizza l'erroresceglie la rappresentazione per cui la differenza tra il valore rappresentato e quello vero è la più piccola possibile: il maggior numero di bit frazionari $m$ compatibile con l'intervallo ($n=W-m$ bit interi, con U se $x\ge0$, con S se $x<0$). Poi $C=\mathrm{round}(x\cdot2^m)$, scritto in esadecimale (per un negativo, in complemento a 2), e l'errore $\varepsilon=\frac{C}{2^m}-x$, positivo se in eccesso, ha modulo $\le2^{-(m+1)}$. Se invece è dato l'errore massimo, i bit minimi si ricavano da $2^{-(m+1)}\le\varepsilon_{max}$.Rappresentare un valore reale in virgola fissa - formato ottimo ed errore →.
Altre convenzioni usate in esame
- Il formato è dichiarato dal programmatore: il codice dovrebbe riportare in ogni modulo la normalizzazione scelta, per chi lo legge.
- Intero con segno su 8 bit (come ) corrisponde a 8.0 S; vale .
- L'allineamento di un dato più corto (per esempio quello dell'ADC a 12 bit) in una parola a 16 bit si fa a destra (i due LSB coincidono, normalizzazione intera) oppure a sinistra (i due MSB coincidono, normalizzazione frazionaria): Realizzare un filtro o un regolatore a virgola fissaRealizzare in C un filtro a virgola fissa vuol dire scegliere per ogni dato il formato (coefficienti $<1$ in 0.16 U, coefficienti $>1$ in 1.15, 4.12, 5.11 S...), moltiplicare con aritmetica a 32 bit ($16\times16\to32$) e riportare il prodotto al formato di arrivo con uno shift a destrascorrimento dei bit verso destra: equivale a dividere per una potenza di 2; per sommare due prodotti con scale diverse si fa lo shift prima di sommare. Con $a+b=2^{16}$ il filtro $y=\big(a,y_{k-1}+b,(u\ll4)\big)\gg16$ non va in overflow in un
uint32_t. Nel codice il formato di ogni variabile va dichiarato in un commento; la funzione $\sin x\approx x-\frac{x^3}6+\frac{x^5}{120}$ mostra come si approssima una funzione con polinomi a coefficienti in virgola fissa.Realizzare un filtro o un regolatore a virgola fissa →. - L'errore di rappresentazione si indica con segno positivo se il valore rappresentato è in eccesso rispetto al vero.
Errori comuni
- Dimenticare che in un formato S il segno fa parte di (1.15 S: un bit di segnoil bit più significativo: vale 1 per i negativi e 15 frazionari, non 16 frazionari).
- Leggere un codice negativo come naturale (o viceversa) perché si è sbagliata la "S/U".
- Sommare due numeri con diversi senza riallineare.
- Scambiare Q15 e 0.15: Q15 è 1.15 S (16 bit totali).
Versione ripasso
- Formato n.m su W bit (): ; U: ; S: , il segno è dentro ; risoluzione ; errore max .
- Q15 = 1.15 S, Q7 = 1.7 S; 8.8 S = ; 4.12 U = .
- Decodifica: codice (con segno: sottrarre se MSB=1) diviso . 3.13U = 5,833; 1.15S = ; 9.7S = ; vale (3.13S) o (3.13U).
- Somma: stessa scala. Prodotto: scala ; riallineare con shift (Operazioni in virgola fissa - somma, prodotto e riallineamentoIn virgola fissa il processore opera sugli interi e non sa dov'è la virgola: tocca al programmatore. Regola 1: si sommano solo dati con lo stesso formato (stesso $m$). Regola 2: il prodotto di $n_1.m_1$ per $n_2.m_2$ ha $m_1+m_2$ bit frazionari e il doppio dei bit: va riallineato con uno shift a destra di $m_2$ posizioni (per riportarlo a $m_1$) o preso dalla parte alta. Con la normalizzazione frazionaria $1.15$ il prodotto è $2.30$ e basta uno shift a sinistra di 1 prima di prendere la parte alta. I fattori di scala si scelgono per evitare overflow e perdita di risoluzione.Operazioni in virgola fissa - somma, prodotto e riallineamento →).
- Scelta del formato ed errore: Rappresentare un valore reale in virgola fissa - formato ottimo ed errorePer rappresentare un reale $x$ su $W$ bit a virgola fissa si sceglie il formato che minimizza l'erroresceglie la rappresentazione per cui la differenza tra il valore rappresentato e quello vero è la più piccola possibile: il maggior numero di bit frazionari $m$ compatibile con l'intervallo ($n=W-m$ bit interi, con U se $x\ge0$, con S se $x<0$). Poi $C=\mathrm{round}(x\cdot2^m)$, scritto in esadecimale (per un negativo, in complemento a 2), e l'errore $\varepsilon=\frac{C}{2^m}-x$, positivo se in eccesso, ha modulo $\le2^{-(m+1)}$. Se invece è dato l'errore massimo, i bit minimi si ricavano da $2^{-(m+1)}\le\varepsilon_{max}$.Rappresentare un valore reale in virgola fissa - formato ottimo ed errore →. Errore + se in eccesso.
- Errori: segno non in ; S/U scambiati; diversi in somma; Q15 ≠ 0.15.
Esercizi su questo argomento
- Esercizio 1 · da reale a esadecimale con formato ottimo, errore e bit minimi (temi d'esame febbraio 2023, gennaio 2022 e settembre 2026)
- Esercizio 2 · da esadecimale a decimale con formato assegnato (temi d'esame febbraio 2023, gennaio 2025, gennaio 2021 e luglio 2020)
- Esercizio 4 · somme in complemento a 2, overflow e flag (temi d'esame gennaio 2023, luglio 2026 e esempi di prova)
- Esercizio 6 · divisione con una ALU a 8 bit, fattore di scala e serie (temi d'esame gennaio 2021, gennaio 2022, dicembre 2020 e luglio 2026)
Teoria collegata
- Formulario - elettronica industriale
- Numeri binari e complemento a due
- Operazioni in virgola fissa - somma, prodotto e riallineamento
- Rappresentare un valore reale in virgola fissa - formato ottimo ed errore
- Realizzare un filtro o un regolatore a virgola fissa
- Virgola mobile - formato IEEE 754 e formato a 16 bit