Tipos de coma flotante de tamaño fijo

92

En los encabezados stdint.h(C99), boost / cstdint.hpp y cstdint(C ++ 0x) se encuentra, entre otros, el tipo int32_t.

¿Existen tipos de coma flotante de tamaño fijo similares? Algo como float32_t?

Pietro
fuente
4
¿Por qué necesitas algo así?
AraK
41
Necesita algo así cuando tiene una estructura de datos con un valor de punto flotante y también desea saber exactamente cuál es su tamaño.
mafia
5
@mobrule: si solo necesita saber cuál es el tamaño, use el sizeofoperador. Un tipo como este sería útil cuando un algoritmo requiere que tenga un tamaño específico conocido.
Stephen Canon
6
@Stephen Canon: sí, para cuando quieras garantizar cuál es el tamaño. Digamos que una instancia de su estructura de datos se ajustará a 64 bits y se puede pasar por valor a alguna biblioteca externa.
mafia
7
@StephenCanon Considere una biblioteca de serialización multiplataforma. ¿Cómo se sizeofpuede utilizar para resolver el problema de ordenar y deshacer consistentemente tipos flotantes?
Kyle Strand

Respuestas:

48

No existe nada parecido en los estándares C o C ++ en la actualidad. De hecho, ni siquiera hay garantía de que floatsea ​​un formato binario de punto flotante.

Algunos compiladores garantizan que el floattipo será el formato binario de 32 bits IEEE-754. Algunos no. En realidad, floates del tipo IEEE-754 singleen la mayoría de las plataformas no integradas, aunque se aplican las advertencias habituales sobre algunos compiladores que evalúan expresiones en un formato más amplio.

Hay un grupo de trabajo que discute la adición de enlaces de lenguaje C para la revisión de 2008 de IEEE-754, que podría considerar recomendar que se agregue tal typedef. Si esto se agrega a C, espero que el estándar C ++ siga su ejemplo ... eventualmente.

Stephen Canon
fuente
3
Independientemente de IEEE-754 o no, todavía no evitará problemas de portabilidad endian.
Mark B
1
@Pietro: cambiar el idioma no afectará la compatibilidad de su hardware, solo impediría que algunos hardware cumplan. ¿Cómo garantizaría una IEEE FP la portabilidad de la ayuda?
Potatoswatter
1
@Potatoswatter: alentaría a los proveedores de hardware a proporcionar soluciones compatibles. Si la parte a admite el estándar C sin necesidad de hacks de bibliotecas de flotación suave y la parte b no lo hace, esa es una ventaja de mercado para la parte a.
Stephen Canon
2
@Potatoswatter: (Casi) a nadie le importa la velocidad del hardware. Nos preocupamos por la velocidad del software que se ejecuta en el hardware. El software puede ser más rápido si el hardware en el que se está ejecutando se ajusta a los estándares y el software no necesita detectar y parchear 15 casos especiales diferentes dependiendo de la plataforma en la que se esté ejecutando.
Stephen Canon
8
¿Cómo diablos obtendría una mejor portabilidad al evitar que su código se compile en una serie de arquitecturas de nicho? O confía en que los flotantes sean IEEE, en cuyo caso su código ya se ejecutará en todas las implementaciones compatibles con IEEE y nada más, o no lo hace, en cuyo caso su código se ejecutará en una gama más amplia de sistemas. Si C ++ garantiza el cumplimiento de IEEE, su código no se volvería mágicamente más portátil, simplemente descartaría que alguna vez podría ejecutarse en esas arquitecturas no compatibles. Tu lógica está completamente al revés.
jalf
30

Si desea saber si floates del tipo IEEE de 32 bits, verifique std::numeric_limits<float>::is_iec559. Es una constante en tiempo de compilación, no una función.

Si desea ser más a prueba de balas, también verifique std::numeric_limits<float>::digitsque no estén usando furtivamente el estándar IEEE de doble precisión para float. Debería ser 24.

Cuando se trata de long double, es más importante verificar digitsporque hay un par de formatos IEEE que podrían ser razonablemente: 128 bits (dígitos = 113) u 80 bits (dígitos = 64).

No sería práctico tenerlo float32_tcomo tal porque generalmente desea usar hardware de punto flotante, si está disponible, y no recurrir a una implementación de software.

Potatoswatter
fuente
El long doubleformato en OS X (Intel de 32 y 64 bits) es exactamente el formato doble extendido IEEE-754 almacenado en orden little-endian. No tiene nada de raro. Los bytes 0-7 contienen el campo de significado, y los bytes 8 y 9 contienen los campos de exponente y signo.
Stephen Canon
@ Stephen: son buenas noticias: v). ¿Eso concuerda con los números que publiqué?
Potatoswatter
1
Recuerde que el doble extendido (a diferencia de los otros formatos 754) tiene un bit de significado inicial explícito, por lo que 5.0Ltiene un significado de a000000000000000. Su exponente insesgado es +2, y el sesgo del exponente doble extendido es 3fff, por lo que el exponente sesgado para 5.0L es 4001. El patrón de bytes real cuando se almacena en orden little-endian es 00 00 00 00 00 00 00 a0 01 40, y si lo ve como dos enteros little-endian de 64 bits, verá exactamente lo que observó.
Stephen Canon
(*) doble extendido según lo implementado por Intel en hardware, es decir. En realidad, el formato doble extendido no está definido como los otros dos formatos básicos de IEEE-754 (1985).
Stephen Canon
@Stephen: Estoy bastante seguro de que 4001en little-endian es 01 40 00 00 ...Si nada más, el byte menos significativo es lo primero. Espero que la secuencia a0 01 40aparezca en algún lugar del número (si solo realizaron una rotación) pero no creo que hayas explicado por qué a0y 01 40estás en mitades completamente separadas.
Potatoswatter
18

Si cree que tener typedefs como float32_t y float64_t no es práctico por alguna razón, debe estar demasiado acostumbrado a su sistema operativo conocido, el compilador, que no puede mirar fuera de su nido.

Existe hardware que ejecuta de forma nativa operaciones de punto flotante IEEE de 32 bits y otros que lo hacen de 64 bits. A veces, estos sistemas incluso tienen que comunicarse entre sí, en cuyo caso es extremadamente importante saber si un doble es de 32 bits o 64 bits en cada plataforma. Si la plataforma de 32 bits hiciera cálculos excesivos sobre la base de los valores de 64 bits de la otra, es posible que deseemos lanzar a la precisión más baja según los requisitos de tiempo y velocidad.

Personalmente, me siento incómodo usando flotadores y dobles a menos que sepa exactamente cuántos bits hay en mi plataforma. Más aún si tengo que transferirlos a otra plataforma a través de algún canal de comunicaciones.

EmbeddedCoder
fuente
"Personalmente me siento incómodo usando flotadores y dobles a menos que sepa exactamente cuántos bits hay en mi plataforma. Más aún si tengo que transferirlos a otra plataforma a través de algún canal de comunicaciones". - ¿Quiere decir que usa formatos de archivo de texto? Con estos, existe la desventaja del tamaño del archivo: un flotante de 32 necesita 4 bytes; estos en forma de texto pueden representar solo un número de cuatro dígitos ...
Pietro
3

Actualmente existe una propuesta para agregar los siguientes tipos al idioma:

decimal32
decimal64
decimal128

que algún día será accesible a través de #include <decimal>.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3871.html

Trevor Hickey
fuente
3
Por supuesto, los tipos decimales no son los tipos de coma flotante IEEE 754.
Mike DeSimone
¡ESPERE! ¡También necesitamos decimal24hacer cosas como leer archivos WAV con muestras de 24 bits más fáciles!
tjwrona1992