Esercizio 3calcolo di y = a·x + b e di un polinomio in virgola fissa a 32 bit (temi d'esame gennaio 2026 e settembre 2026)
In questa pagina 4
Testo (tema d'esame gennaio 2026, problema P1; settembre 2026, problema 7).
(i) Determinare il valore di con , , . Il calcolo si esegue a virgola fissa su una ALU a 32 bit, con dati a 16 bit in una codifica frazionaria con segno () o senza () scelta in modo da minimizzare l'errore di rappresentazione. Indicare per il codice esadecimale e il formato, l'errore assoluto su e scrivere un'assegnazione in C per .
(ii) Un programmatore calcola per con , , in aritmetica a 32 bit. (a) Valori di e in formato 0.16 U con arrotondamento ed errori; (b) il valore reale di e la rappresentazione interna in 1.15 U per ; (c) il valore di calcolato in 0.16 e l'errore.
Teoria usata: 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 →, 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 →, 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 →.
(i) Formati e codici
Si sceglie per ciascun dato il formato con il massimo numero di bit frazionari che contiene il valore:
- : positivo, minore di 1: 0.16 U, ();
- : negativo, : 3.13 S (segno + 2 bit interi + 13 frazionari), ();
- : positivo, tra 1 e 2: 1.15 U, ();
- : il valore atteso è : positivo e minore di 1: 0.16 U.
Riallineamento del calcolo
Il prodotto ha bit frazionari. Per sommare (15 bit frazionari) i due addendi devono avere lo stesso numero di bit frazionari: si sposta a sinistra di 14 posti (29 bit frazionari). La somma ha 29 bit frazionari; per ottenere in 0.16 U (16 bit frazionari) si sposta a destra di 13: Controllo di non overflow su 32 bit con segno: ; ; la somma è ✓.
Numeri: ; ; somma (a 29 bit frazionari vale ); : , cioè .
Errore assoluto su : (dovuto ai tre arrotondamenti dei dati e al troncamento dello shift finale).
In C (con uint16_t a16=0x599A; int16_t x16=(int16_t)0xA8CD; uint16_t b16=0xC28F;):
y16 = (uint16_t)( ( (int32_t)a16 * (int32_t)x16 + ((int32_t)b16 << 14) ) >> 13 ); // y in 0.16 UNotare i cast a int32_t prima del prodotto (per evitare l'overflow di int a 16 bit e perché x16 è con segno) e che lo shift a destra di un intero con segno è aritmetico.
| Dato | Formato | Codice | Errore |
|---|---|---|---|
| 0.16 U | |||
| 3.13 S | |||
| 1.15 U | |||
| 0.16 U |
(ii) Polinomio per il seno
(a) Coefficienti in 0.16 U con arrotondamento: : , ; : , . ( non è rappresentabile in 0.16 U: si tratta come stesso, senza moltiplicazione.)
(b) Il valore di . rad, in 1.15 U (): ; il valore realmente usato è (errore ).
(c) Il valore calcolato. Il polinomio con coefficienti esatti calcolato in dà . Il processore calcola: , , (tutti in 1.15); poi in formato 0.16 U (i prodotti hanno 31 bit frazionari: si scartano 15 bit; converte 1.15 in 0.16 U). Risultato: ; errore rispetto a : . Rispetto a l'errore è : è dominato dall'errore di troncamento della serie di Taylor (ordine 5), non dalla rappresentazione.
Errori comuni
- Usare per il formato 2.14 S (non contiene , intervallo ).
- Sommare (29 bit frazionari) e (15) senza riallineare.
- Fare il prodotto in 16 bit (
uint16_t*int16_tè promosso aintche può andare bene su ARM a 32 bit, ma il risultato va riportato con shift; con tipi più corti si perde il segno). - Dimenticare che il risultato dello shift su un intero negativo va ottenuto con shift aritmetico.
Versione ripasso
Testo. con in virgola fissa a 32 bit (16 bit per dato, formati ottimi); con coefficienti in 0.16 U (gennaio e settembre 2026).
- Formati: 0.16U
599A; 3.13SA8CD; 1.15UC28F; 0.16U. - Riallineamento: ha 29 bit frazionari, ; ; errore (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 →).
- C:
y=(uint16_t)(((int32_t)a*(int32_t)x+((int32_t)b<<14))>>13);(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 unuint32_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 →). - Seno: (), (); → 1.15U
860B; (, errore sul polinomio, su ). - Errori: in 2.14S; somma tra scale diverse; prodotto senza cast; shift logico (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 →).