simple que punto numero normalizado normalizada mantisa informatica flotante exponente estandar ejemplos coma c floating-point ieee-754

que - punto flotante plc



¿Es seguro asumir que el punto flotante se representa utilizando flotantes IEEE754 en C? (6)

Casi todas las arquitecturas comunes ahora usan IEEE-754, esto no es requerido por el estándar. Solía ​​haber arquitecturas antiguas no IEE-754, y algunas todavía podrían estar alrededor.

Si el único requisito es el intercambio de datos de red, mi consejo es:

  • Si se define __STDC_IEC_559__ , solo use el orden de la red para los bytes y suponga que tiene el estándar IEE-754 para flotar y duplicar.
  • Si no se define __STDC_IEC_559__ , use un formato de intercambio especial, que podría ser IEE-754 (un solo protocolo, o cualquier otra cosa) necesita una indicación de protocolo.

El punto flotante es la implementación definida en la C. Por lo tanto, no hay garantías.

Nuestro código debe ser portátil, estamos discutiendo si es aceptable o no utilizar flotantes IEEE754 en nuestro protocolo. Por razones de rendimiento, sería bueno si no tuviéramos que realizar conversiones entre un formato de punto fijo al enviar o recibir datos.

Si bien sé que puede haber diferencias entre plataformas y arquitecturas con respecto al tamaño de long o wchar_t . Pero parece que no puedo encontrar ninguna información específica sobre el float y el double .

Lo que encontré hasta ahora es que el orden de bytes se invirtió en las plataformas big endian. Si bien hay plataformas sin soporte de punto flotante, un código que contiene float y double ni siquiera se vincularía. De lo contrario, las plataformas parecen apegarse a la precisión simple y doble IEEE754.

Entonces, ¿es seguro asumir que el punto flotante está en IEEE754 cuando está disponible?

EDITAR: En respuesta a un comentario:

¿Cuál es su definición de "seguro"?

Por seguro, quiero decir, el patrón de bits en un sistema significa lo mismo en el otro (después de la rotación de bytes para tratar con la endianidad).


Como han mencionado otros, existe la macro __STDC_IEC_559__ , pero no es muy útil porque solo la establecen compiladores que implementan completamente el anexo respectivo en el estándar C. Hay compiladores que implementan solo un subconjunto, pero aún tienen (en su mayoría) soporte de punto flotante IEEE utilizable.

Si solo le preocupa la representación binaria, debe escribir una prueba de características que compruebe los patrones de bits de ciertos números flotantes. Algo como:

#include <stdint.h> #include <stdio.h> typedef union { double d; uint64_t i; } double_bits; int main() { double_bits b; b.d = 2.5; if (b.i != UINT64_C(0x4004000000000000)) { fprintf(stderr, "Not an IEEE-754 double/n"); return 1; } return 0; }

Verifica un par de números con diferentes exponentes, mantisas y signos, y deberías estar en el lado seguro. Dado que estas pruebas no son caras, incluso puede ejecutarlas una vez en tiempo de ejecución.


Esencialmente, todas las arquitecturas en uso actual sin tarjetas perforadas, incluidas las arquitecturas integradas y las arquitecturas de procesamiento de señales exóticas, ofrecen uno de los dos sistemas de punto flotante:

  • IEEE-754.
  • IEEE-754 excepto por bla . Es decir, en su mayoría implementan 754, pero descuentan algunos de los bits más caros y / o complicados.

Las salidas baratas más comunes:

  • Flushing denormals a cero. Esto invalida ciertos teoremas a veces útiles (en particular, el teorema de que ab puede representarse exactamente si 0 <= a/2 <= b <= a*2 ), pero en la práctica generalmente no será un problema.
  • La falta de reconocimiento de inf y NaN como especial. Estas arquitecturas no seguirán las reglas relativas a inf y NaN como operandos, y pueden no saturarse a inf , en lugar de producir números que son más grandes que FLT_MAX , que generalmente serán reconocidos por otras arquitecturas como NaN .
  • Redondeo adecuado de la división y la raíz cuadrada. Es mucho más fácil garantizar que el resultado esté dentro de 1-3 ulps del resultado exacto que dentro de 1/2 ulp. Un caso particularmente común es que la división se implemente como multiplicación + recíproca, lo que pierde un poco de precisión.
  • Menos o ningún dígito de guardia. Este es un insólito inusual, pero significa que otras operaciones pueden ser de 1-2 ulps.

BUUUUT ... incluso aquellos con excepción de las arquitecturas blah todavía utilizan la representación de los números de IEEE-754. Además de los problemas de ordenamiento de bytes, los bits que describen una float o double en la arquitectura A tienen esencialmente la garantía de tener el mismo significado en la arquitectura B.

Entonces, mientras lo único que te importa es la representación de los valores, estás totalmente bien. Si le interesa la coherencia de las operaciones en varias plataformas, es posible que deba realizar algún trabajo adicional.

EDITAR : Como lo menciona Chux en los comentarios, una fuente adicional común de inconsistencias entre plataformas es el uso de una precisión extendida, como la representación interna de 80 bits del x87. Eso es lo opuesto a una versión barata, y (con el tratamiento adecuado) se ajusta completamente tanto a IEEE-754 como a la norma C, pero también causará que los resultados difieran entre las arquitecturas, e incluso entre las versiones del compilador y el siguiente código aparentemente secundario y no relacionado cambios Sin embargo: un ejecutable x86 / x64 en particular NO producirá resultados diferentes en diferentes procesadores debido a la precisión extendida.


Estrictamente hablando, no es seguro asumir un soporte de punto flotante; En general, la gran mayoría de plataformas lo soportarán. Las excepciones notables incluyen sistemas VMS (ahora en desuso) que se ejecutan en chips Alpha

Si tiene el lujo de verificar el tiempo de ejecución, considere la paranoia , una herramienta de investigación de puntos flotantes escrita por William Kahan .

Edición: parece que su aplicación está más preocupada por los formatos binarios en lo que respecta al almacenamiento y / o la serialización. Yo sugeriría reducir su alcance al elegir una biblioteca de terceros que admita esto. Usted podría hacer peor que los búferes de protocolo de Google


Hay una macro para comprobar (desde C99):

C11 §6.10.8.3 Macros de características condicionales

__STDC_IEC_559__ La constante entera 1, que pretende indicar la conformidad con las especificaciones en el anexo F (IEC 60559 aritmética de punto flotante).

IEC 60559 (abreviatura de ISO / IEC / IEEE 60559 ) es otro nombre para IEEE-754.

El Anexo F luego establece el mapeo entre los tipos flotantes C y los tipos IEEE-754:

Los tipos flotantes de C coinciden con los formatos IEC 60559 de la siguiente manera:

  • El tipo flotante coincide con el formato único IEC 60559.
  • El tipo doble coincide con el formato doble IEC 60559.
  • El tipo doble largo coincide con un formato extendido IEC 60559, 357) otro formato extendido no IEC 60559, o bien el formato doble IEC 60559.

Le sugiero que tenga que mirar más detenidamente su definición de portátil.

También sugeriría que su definición de "seguro" es insuficiente. Incluso si la representación binaria (permitiendo el endianness) está bien, las operaciones en las variables pueden comportarse de manera diferente. Después de todo, hay pocas aplicaciones de punto flotante que no involucran operaciones en variables.

Si desea admitir todas las arquitecturas de host que se hayan creado alguna vez, asumiendo que el formato de punto flotante IEEE es inherentemente inseguro. Tendrá que lidiar con sistemas que admiten diferentes formatos, sistemas que no admiten punto flotante en absoluto, sistemas para los cuales los compiladores tienen conmutadores para seleccionar comportamientos de punto flotante (algunos comportamientos están asociados con formatos que no son IEEE), CPU que tienen un coprocesador opcional (por lo tanto, el soporte de punto flotante depende de si se instala un chip adicional, pero las variantes de la CPU son idénticas), los sistemas que emulan las operaciones de punto flotante en el software (algunos emuladores de este tipo de software son configurables en el tiempo de ejecución), y Sistemas con implementación defectuosa o incompleta de punto flotante (que puede o no estar basado en IEEE).

Si está dispuesto a limitarse al hardware de la época posterior a 2000, su riesgo es menor pero no nulo. Prácticamente todas las CPU de esa época admiten IEEE de alguna forma. Sin embargo, usted todavía (como con las CPU más antiguas) debe considerar qué operaciones de punto flotante desea que sean compatibles y las compensaciones que está dispuesto a aceptar para tenerlas. Las diferentes CPU (o emulación de software) tienen una implementación de punto flotante menos completa que otras, y algunas están configuradas de forma predeterminada para no admitir algunas características, por lo que es necesario cambiar la configuración para habilitar algunas características, lo que puede afectar el rendimiento o la corrección de su código.

Si necesita compartir valores de punto flotante entre aplicaciones (que pueden estar en hosts diferentes con características diferentes, compilados con compiladores diferentes, etc.), entonces deberá definir un protocolo. Ese protocolo puede involucrar el formato IEEE, pero todas sus aplicaciones deberán poder manejar la conversión entre el protocolo y sus representaciones nativas.