2010-03-26 32 views
59

Nelle intestazioni stdint.h (C99), boost/cstdint.hpp e cstdint (C++ 0x) è presente, tra gli altri, il tipo int32_t.Tipi a virgola mobile a dimensione fissa

Esistono tipi di virgola mobile di dimensioni fisse simili? Qualcosa come float32_t?

+4

Perché avete bisogno di qualcosa del genere? – AraK

+1

Pietro, sembra che tu non possa davvero capire come funzionano i float. –

+30

Hai bisogno di qualcosa del genere quando hai una struttura dati con un valore in virgola mobile e vuoi anche sapere esattamente qual è la sua dimensione. – mob

risposta

37

Attualmente non esiste nulla di simile negli standard C o C++. In effetti, non c'è nemmeno la garanzia che lo float sia un formato binario a virgola mobile.

Alcuni compilatori garantiscono che il tipo float sarà il formato binario a 32 bit IEEE-754. Alcuni no. In realtà, float è in realtà il tipo IEEE-754 single su maggior parte delle piattaforme non incorporate, sebbene si applichino le solite avvertenze su alcuni compilatori che valutano espressioni in un formato più ampio.

Esiste un gruppo di lavoro che discute l'aggiunta di binding di linguaggio C per la revisione 2008 di IEEE-754, che potrebbe prendere in considerazione la possibilità di aggiungere tale typedef. Se questo fosse aggiunto a C, mi aspetto che lo standard C++ segua l'esempio ... alla fine.

+0

Spero che il gruppo di lavoro leghi C/C++ a IEEE-754. Quindi, se vuoi la portabilità, puoi ottenerla più facilmente e, se non ne hai bisogno, puoi continuare a utilizzare i vecchi tipi di piattaforma dipendenti. – Pietro

+2

Indipendentemente dall'EEEE-754 o meno, non impedirà comunque i problemi di portabilità endian. –

+1

@Pietro: la modifica della lingua non influirà sulla compatibilità hardware, impedirà solo la conformità dell'hardware. In che modo un IEEE FP garantisce la portabilità? – Potatoswatter

22

Se si desidera sapere se il proprio float è il tipo IEEE a 32 bit, controllare std::numeric_limits<float>::is_iec559. È una costante in fase di compilazione, non una funzione.

Se si desidera essere più a prova di proiettile, controllare anche std::numeric_limits<float>::digits per assicurarsi che non stiano subdolamente utilizzando la precisione doppia standard IEEE per float. Dovrebbe essere 24.

Quando si tratta di long double, è più importante controllare digits perché ci sono un paio di formati IEEE che potrebbe essere ragionevolmente: 128 bit (cifre = 113) o 80 bit (cifre = 64).

Non sarebbe pratico avere float32_t come tale perché di solito si desidera utilizzare l'hardware a virgola mobile, se disponibile, e non ricorrere a un'implementazione software.

+0

Il formato 'long double' su OS X (sia Intel a 32 bit che a 64 bit) è esattamente il doppio formato esteso IEEE-754 archiviato nell'ordine little-endian. Niente di strano in tutto ciò. I byte 0-7 contengono il campo significato e i byte 8 e 9 contengono i campi esponente e segno. –

+0

@Stephen: questa è una buona notizia: v). Questo è in accordo con i numeri che ho postato? – Potatoswatter

+1

Ricordate che il doppio esteso (a differenza degli altri 754 formati) ha un significato significativo e un bit, quindi '5.0L' ha un significato e' a000000000000000'. Il suo esponente imparziale è +2, e il doppio esponente esteso è '3fff', quindi l'esponente parziale per 5.0L è '4001'.Il modello di byte effettivo quando memorizzato nell'ordine little-endian è "00 00 00 00 00 00 00 a0 01 40' e se lo visualizzi come due interi bitenendiani a 64 bit, vedrai esattamente ciò che hai osservato. –

13

Se pensate che avere typedef come float32_t e float64_t non sia pratico per qualsiasi motivo, dovete essere troppo abituati al vostro SO familiare, il compilatore, che non siete in grado di guardare oltre il vostro nido.

Esistono hardware che eseguono in modo nativo operazioni in virgola mobile IEEE a 32 bit e altre che eseguono 64 bit. A volte tali sistemi devono anche comunicare tra loro, nel qual caso è estremamente importante sapere se un doppio è a 32 bit o 64 bit su ciascuna piattaforma. Se la piattaforma a 32 bit eseguisse calcoli eccessivi sulla base dei valori a 64 bit dell'altro, potremmo voler eseguire il cast sulla precisione inferiore in base ai requisiti di temporizzazione e velocità.

Personalmente mi sento a disagio nell'usare i float e il doppio a meno che non sappia esattamente quanti bit sono sulla mia platina. Ancor di più se devo trasferirli su un'altra piattaforma su qualche canale di comunicazione.

+0

"Personalmente mi sento a disagio nell'usare float e double se non so esattamente quanti bit sono sul mio platfrom, tanto più se devo trasferirli su un'altra piattaforma su qualche canale di comunicazione." - Vuoi dire che usi i formati di file di testo? Con questi c'è lo svantaggio della dimensione del file: un 32 float ha bisogno di 4 byte; questi in forma di testo possono rappresentare solo un numero di quattro cifre ... – Pietro

Problemi correlati