2013-07-30 9 views
5

Per un'applicazione C che sto implementando, devo essere in grado di leggere e scrivere un set di valori di configurazione in un file. Questi valori sono numeri in virgola mobile. In futuro è possibile che un'altra applicazione (che potrebbe essere scritta in C++, Python, Perl, ecc ...) utilizzi questi stessi dati, quindi questi valori di configurazione devono essere memorizzati in un formato ben definito che sia indipendente dal compilatore e dalla macchina .Memorizzazione di numeri in virgola mobile in un file

Le funzioni di conversione dell'ordine byte (ntoh/hton) possono essere utilizzate per gestire l'endianità, tuttavia qual è il modo migliore per aggirare i diversi significati del valore "float"? C'è un metodo comune per immagazzinare i galleggianti? Arrotondare e troncare non è un problema, purché sia ​​definito.

+2

Il modo migliore per memorizzare un oggetto mobile (o qualsiasi altro valore), indipendente dalla piattaforma, è in forma di testo. Archiviandolo in formato binario non funzionerà, e l'uso di funzioni di endianess non sarà di aiuto in quanto non è definito alcun endianess per le rappresentazioni binarie di valori in virgola mobile. –

+2

@JoachimPileborg Anche se non ci può essere endianness definita standard per le rappresentazioni in virgola mobile binario, è abbastanza facile imporne uno da solo. Tutto quello che devi fare è decretare che i valori in virgola mobile sono memorizzati, ad esempio, in formato big endian. –

+0

È possibile utilizzare un tipo standard come IEEE754 raddoppia – SheetJS

risposta

5

Probabilmente ci sono due opzioni principali:

  1. Conservare in formato testo. Qui dovresti standardizzare su un particolare formato usando un separatore decimale ben definito e usare la notazione scientifica, cioè 6.66e42.
  2. Memorizza in formato binario utilizzando lo standard IEEE754. Utilizzare il tipo di dati a 4 o 8 byte. E come hai notato, dovresti accontentarti di una convention di endianness.

Un formato di testo è probabilmente più portabile perché ci sono macchine che non interpretano nativamente IEEE754. Detto questo, tali macchine sono rare in questi tempi.

+0

Perché utilizzare decimale? –

+0

@Eric Per la portabilità e la leggibilità umana –

+2

Decimale non offre la portabilità poiché la corretta conversione tra numeri decimali e virgola mobile binario non è supportata come dovrebbe essere. La maggior parte degli standard di lingua non richiede conversioni correttamente arrotondate e varie implementazioni non garantiscono loro. Al contrario, l'esadecimale è facile da convertire, anche se devi scrivere la tua routine di conversione. –

0

IEEE 754 o ISO/IEC/IEEE 60559: 2011, è lo standard per il punto mobile utilizzato dalla maggior parte delle lingue.

Per C, è preso ufficialmente dallo standard in C11. (C11 allegato F IEC 60559 aritmetica in virgola mobile)

+0

L'allegato F è facoltativo; un'implementazione deve solo aderirvi se definisce '__STDC_IEC_559__'. –

0

Per piccole quantità di dati, come i valori di configurazione, andare con il testo non binario. Se vuoi, vai per il testo strutturato di qualche forma, come JSON, XML. Decidi su quante cifre scrivere per rappresentare un numero in virgola mobile in base alle tue esigenze.

Poiché la gamma della portabilità richiesta (tra lingue, sistemi operativi, tempo, spazio, ecc.) Aumenta così la forza dell'argomento a favore del testo diventa più forte.

4

Le funzioni di input/output con formattazione C dispongono di un identificatore di formato per questo, %a. Formatta un numero in virgola mobile in un formato esadecimale in virgola mobile, [-] 0x h. hhhh p ± d. Cioè, ha un segno "-" se necessario, cifre esadecimali per la parte della frazione, tra cui un punto di radix, una "p" (per "potenza") per avviare l'esponente e un esponente firmato di due (in decimale).

Finché l'implementazione C utilizza il punto di virgola mobile binario (o qualsiasi punto mobile in modo che il suo FLT_RADIX sia una potenza di due), la conversione con il formato %a dovrebbe essere esatta.

+0

Come si legge un testo di questo tipo da lingue diverse da C? –

+1

@DavidHeffernan: il formato esadecimale in virgola mobile è facile da convertire in e in virgola mobile. Quando si convertono i numeri che provengono dallo stesso formato binario (quindi, non ci sono cifre aggiuntive che devono essere arrotondate), non ci sono problemi di arrotondamento. –

+0

Ma potrebbe non essere banale in lingue diverse da C. Ad esempio, quale sarebbe il codice per farlo in Perl? C'è una funzione integrata per farlo? Ho il sospetto che per molte lingue avresti bisogno di tirare il tuo. Ecco perché le persone possono optare per la convenienza dei decimali a scapito di una perdita di precisione di andata e ritorno. –

Problemi correlati