2012-08-13 19 views
7

Ho una situazione che richiede di rappresentare un float in un singolo char. L'intervallo che questo 'minifloat' deve rappresentare è da 0 a 10e-7, quindi possiamo sempre presumere che il numero sia + ve, e l'esponente -ve per risparmiare spazio.Rappresenta un float in un singolo byte

La rappresentazione a cui ho pensato di andare è 3 bit di esponente e 5 bit mantissa (con 1 bit implicito), con l'esponente in base 10, ovvero x = man * 10^exp.

Per convertire da un galleggiante al mio minifloat, ho intenzione di usare frexp, e utilizzare alcuni matematica convertire da base 2 a base 10.

Si tratta di un approccio ragionevole? O ci sono modi migliori per raggiungere questo obiettivo?

risposta

7

In realtà è necessario che il valore sia a virgola mobile (vale a dire avere una precisione approssimativamente costante man mano che il valore si ridimensiona)? Che cosa hai intenzione di fare con questi valori?

Un'idea molto più semplice (e più efficiente) sarebbe interpretare 8 bit come un numero di punto fisso senza segno con una scala implicita di 1e-7. Per esempio: bit

float toFloat(uint8_t x) { 
    return x/255.0e7; 
} 

uint8_t fromFloat(float x) { 
    if (x < 0) return 0; 
    if (x > 1e-7) return 255; 
    return 255.0e7 * x; // this truncates; add 0.5 to round instead 
} 
+0

Questo fa il lavoro, grazie! – Dunnie

4

Se serve ai propri scopi, è ragionevole utilizzare tale formato come formato di archiviazione o trasmissione, ovvero per registrare i dati in uno spazio ridotto. Dovresti verificare che gli errori di arrotondamento di questo formato non siano troppo grandi per le tue esigenze, che l'intervallo sia adatto, eccetera.

Questo non sarebbe un buon formato per il calcolo, perché sarebbe lento sul normale hardware.

Non capisco che conversione di base si farebbe. Se si dispone di un numero a virgola mobile IEEE-754 in un numero float, il processo di conversione in o dal formato a 8 bit è uno di arrotondamento del significato (frazione) quando si passa al formato più ristretto e di regolazione del bias esponenziale , oltre a gestire casi speciali (denormali, overflow, NaN). Ciò comporterebbe solo l'aritmetica binaria, non decimale.

Come nota a parte, il termine corretto per la parte frazione di un numero in virgola mobile è "frazione" o "significante" (il termine utilizzato nello standard IEEE-754). Una "mantissa" è la parte frazionaria di un logaritmo.

0

5 mantissa dati 32 situazioni diverse da 1.00 a 9.00 con la dimensione minima del gradino 0,25

1,00 1,25 1,50 1,75 2,00 8,75 9,00 ....

3 esponenti possono dare 8 diverse situazioni 10^0 (che è 1) 10^-2 10^-3 10^-4 .... infine 10^-7

L'errore della parte della frazione è 0,25. Se i tuoi calcoli possono compensare questo errore, puoi usare questo.

3

Un'alternativa è utilizzare un array statico di 256 float (o doppio) che sceglierete in base ai vostri criteri.

Quindi la conversione unsigned char -> float/double è banale ...

Il valore di conversione float/double-> unsigned è un po 'più complicato (trova il float più vicino nell'array statico); costerebbe circa 8 confronti con un algoritmo di ricerca binario ingenuo, ma potreste trovare meglio in base al modo in cui avete scelto i valori nell'array statico.

Ovviamente, le operazioni verranno eseguite con virgola mobile/doppia.

Problemi correlati