rappresentazione testuale esatta di un IEEE “doppio”
-
21-09-2019 - |
Domanda
Ho bisogno di rappresentare un IEEE 754-1985 doppia (64 bit) numero a virgola mobile in una forma testuale leggibile, con la condizione che la forma testuale può essere analizzato di nuovo in esattamente il stesso (bit per bit) numero.
Questo è possibile / pratico di fare a meno solo stampare i byte prime? Se sì, il codice per fare questo sarebbe molto apprezzato.
Soluzione
L'opzione migliore: Utilizzare il formato di punto di C99 esadecimale mobile:
printf("%a", someDouble);
Corde prodotta in questo modo può essere riconvertito in double
con la funzione strtod( )
C99, e anche con le funzioni scanf( )
. Diverse altre lingue supportano questo formato. Alcuni esempi:
decimal number %a format meaning
--------------------------------------------
2.0 0x1.0p1 1.0 * 2^1
0.75 0x1.8p-1 1.5 * 2^-1
Il formato esadecimale ha il vantaggio che tutte le rappresentazioni sono esattamente . Così, convertendo la corda in virgola mobile darà sempre il numero originale, anche se qualcuno cambia la modalità di arrotondamento in cui avviene la conversione. Questo non è vero per i formati inesatte.
Se non si desidera utilizzare il formato esadecimale per qualsiasi motivo, e sono disposti a supporre che la modalità di arrotondamento sarà sempre intorno al più vicino (il default), allora si può ottenere via con la formattazione dei dati come decimali con almeno 17 cifre significative. Se si dispone di una routine di conversione correttamente arrotondato. (La maggior parte - non tutte - le piattaforme fanno), questo garantirà che si può fare un viaggio di andata da doppia a stringa e viceversa, senza alcuna perdita di precisione
Altri suggerimenti
Audio come si vuole algoritmo di Burger (PDF):
Nella schermata in formato libero, l'algoritmo genera il breve stringa di output correttamente arrotondata che converte lo stesso numero se letta nel indipendentemente da come la Lettore rompe i legami quando si aggira.
codice sorgente di esempio (in C e Scheme) è disponibile come bene.
Questa è l'algoritmo utilizzato in Python 3.x per garantire float
s possono essere convertite in stringhe e indietro senza alcuna perdita di precisione. In Python 2.x, float
s erano sempre rappresentate con 17 cifre significative perché:
repr(float)
produce 17 cifre significative perché si scopre che è abbastanza (sulla maggior parte delle macchine) in modo cheeval(repr(x)) == x
esattamente per tutti gli oggetti finitix
, ma arrotonda a 16 cifre, non è sufficiente per fare quella vera. (Fonte: http://docs.python.org/tutorial/floatingpoint.html )
Il framework .NET ha un formato di andata e ritorno per questo:
string formatted = myDouble.ToString("r");
Dalla documentazione:
Il andata e ritorno specificatore garantisce che un valore numerico convertito in una stringa verrà analizzato nuovamente dentro lo stesso valore numerico. Quando un valore numerico è formattato utilizzando questo identificatore, è prima testata utilizzando il formato generale, con 15 spazi di precisione per un Doppie e 7 spazi di precisione per un Singolo. Se il valore è successo analizzato indietro allo stesso valore numerico, è formattato con il generale di formato. Tuttavia, se il valore non viene analizzato correttamente indietro allo stesso valore numerico, quindi il valore viene formattato utilizzando 17 cifre di precisione per una doppia e 9 cifre di precisione per una singola.
Questo metodo potrebbe naturalmente essere ricreato nella maggior parte qualsiasi lingua.
Sì, si può fare, anche se l'attuazione dipende dalla lingua. L'idea di base è semplicemente quello di stamparlo con sufficiente precisione.
Si noti che il contrario è non vero però:. Alcuni numeri che possono essere rappresentati con precisione in decimali semplicemente non possono essere rappresentati in binario