Precisione e conversioni in virgola mobile

0

Sto cercando di creare una classe in cui l'utente possa calcolare le operazioni mobili con una precisione particolare. Ad esempio, se l'utente desidera avere una precisione fino a 4 cifre, tutto inferiore a 0,0001 è zero e tutto ciò che è più grande di 9999 è inf.

Penso che il modo migliore sia quello di creare una matrice di bit (o forse di byte) per memorizzare il segno, la mantissa e l'esponente. Ad esempio, con una precisione di 4 cifre decimali, ho potuto calcolare quanti bit avrei bisogno di memorizzare il valore più piccolo e più grande e quindi creare array di quella dimensione.

Questo mi porta a due delle mie domande:

  1. Perché la precisione singola usa esattamente 8 bit per l'esponente e 24 per la mantissa (IEEE 754) anziché 10 e 53, o 12 e 51? È in qualche modo rilevante o è solo uno standard?
  2. Supponendo che avrò bisogno di 4 cifre di precisione per 9999, avrei bisogno di 14 bit ma quanto spazio ho bisogno per mantenere 0,0001 in 4 (decimale) precisione della cifra?

Se la risposta alla prima domanda è "è solo uno standard" ho ancora un'altra domanda:

  • Come faccio a scegliere il miglior esponente e mantissa per il mio problema?

Si prega di ignorare il fatto che i numeri più grandi e più piccoli potrebbero essere calcolati qui, come li farò solo "se". Non voglio usare double / float / etc per questo ho bisogno di come mi aspetto di utilizzare più memoria di un doppio avrebbe bisogno, ma non voglio usare troppo spazio.

    
posta MaLiN2223 15.03.2016 - 20:52
fonte

2 risposte

6

Implementazione del tuo sistema numerico

I am trying to build a class where user can compute floating operations with a particular accuracy. For example, if the user wants to have up to 4 digit accuracy, everything less than 0.0001 is zero and everything bigger than 9999 is inf.

Se si richiede che ci sia un numero (massimo) specifico di cifre dopo il punto decimale, il sistema che si sta descrivendo è un sistema punto fisso , al contrario di un sistema a virgola mobile .

Un modo semplice per implementare un tale sistema è di memorizzare i numeri come numeri interi, scalati per un fattore di scala di 10000. Quindi, il valore (interno) 20000 rappresenterebbe 2.0000. Quindi le operazioni aritmetiche (add / sottrarre / moltiplicare / dividere) possono essere implementate direttamente sul valore interno. Per la moltiplicazione, è necessario dividere per il fattore di scala dopo aver moltiplicato i valori interni. Per la divisione, devi moltiplicare il numeratore prima di eseguire la divisione.

Poiché 10000 rappresenta 1.0000 e si desidera memorizzare valori fino a 9999.0000, il valore interno più grande che si desidera memorizzare sarà 99990000. log2 (99990000) è poco meno di 27, quindi un numero intero a 32 bit sarebbe sufficiente per quello. Tuttavia, dovrai moltiplicare e dividere il tipo più ampio (ad esempio 64 bit) per i valori intermedi.

Vedi anche Qual è il modo migliore per fare il punto fisso matematica? su stackoverflow.

Perché 8 bit di Esponente per float ?

8 bit di esponente forniscono numeri fino a circa 1,0e38. Penso che la ragione per cui float e double usano questo numero di cifre esponenti è semplicemente che la maggior parte dei calcoli effettivi non coinvolgono quantità più grandi di questa. Ci sono numeri rilevanti dal punto di vista fisico più grandi di questo (il numero di Eddington , ad esempio, ma suppongo che semplicemente non si girino su quello spesso nei calcoli.Per la maggior parte delle applicazioni reali (pun intended!), se hai un extra disponibile, puoi trarre maggiore vantaggio dall'usarlo nella mantissa.

Se hai molte più cifre binarie, diciamo il doppio, puoi aggiungere 29 bit alla mantissa e 3 bit all'esponente (favorendo, come ho già detto, la mantissa). Ciò consente di gestire i valori compresi nell'intervallo 1e-308 .. 1e308. Non ricordo di aver mai dovuto fare un calcolo con una quantità maggiore di quella. Ma ci sono implementazioni specialistiche disponibili per questi casi (come CLN ).

Potresti trovare utile leggere l'articolo di Wikipedia su IEEE 754 .

    
risposta data 31.03.2016 - 09:58
fonte
1

La precisione singola utilizza un totale di 32 bit e non 64 bit perché è la precisione singola . L'utilizzo di 10 + 52 bit non risparmierebbe esattamente molta memoria rispetto alla doppia precisione.

Se chiedete perché 8 + 24 bit per esponente / mantissa: volevano usare 32 bit. Quindi qualsiasi combinazione che aggiunge fino a 32 va. Vorresti un esponente a 24 bit e mantissa a 8 bit? Non molto utile, non abbastanza precisione. L'esponente a 8 bit fornisce un intervallo a 10 ^ + / - 38. Potresti forse andare con 7 bit, ma 6 bit ti darebbero solo pochi miliardi. Non abbastanza.

È un compromesso ragionevole. Non tutti saranno d'accordo che è ottimale, ma tutti saranno d'accordo che è vicino.

    
risposta data 15.03.2016 - 22:22
fonte

Leggi altre domande sui tag