Questo argomento a cui volevo dedicare un po' di tempo e finalmente ho trovato degli esempi semplici come ad esempio
https://spin.atomicobject.com/2012/03/15/simple-fixed-point-math/
La logica di base e' semplice..si deve descrivere un numero a virgola mobile con un numero intero e per farlo lo si moltiplica per un valore fisso (una potenza di 2 nel caso di uso di calcolatore) ed eliminando la parte oltre la virgola.
Fixed = round(float * scale_fact)
Per scale_fact si usando potenze di due perche' e' semplice con lo shift dei byte ottenere il valore desiderato (1<< 4 = 16, 4 shift a sinistra per esempio)
Le operazioni di somma e sottrazione non sono modificate
La moltiplicazione invece diventa
r = (x * y)/(1<<scale_fact)
mentre la divisione
r=(x*(1<<scale_fact))/y
Tutto cio' velocizza i calcoli ma introduce necessariamente una approssimazione (in base al fattore di scala)
Proviamo a fare un esempio concreto
x = 3.141592655
y = 2
scale_fact = 16 = 65536
x1 = pi*65536 = 205321.92 = 205887
y1 = 2*65536 = 131072
r = x1*y1 = 205887*131072 / 655536 = 411744
(si vede chiaramente che, dovendo applicare questo metodo ad un calcolatore, durante l'operazione si deve prevedere una variabile di tipo superiore al risultato....cerco di spiegarmi meglio...anche se gli operando sono entrambi byte ed il risultato e' un byte durante il calcolo e' necessario l'uso di una word)
riconvertendo il tutto
r = 411744/65536 = 6.2831726 (il valore dovrebbe essere 6.2831853...)
passando ad uno scale_fact = 8 (256)
x1 = pi*256 = 804
y1 = 2*256 = 512
r = 2526*512/256 = 1608
r = 1608/256 =6.28125 (il valore dovrebbe essere 6.2831853...)
passando ad uno scale_factr = 4 si ha un valore di x*y=6.25
in sintesi l'ordine dell' errore e'
16 bit : E-6
8 bit : E-4
4 bit : E-3