Representación textual exacta de un “doble” IEEE
-
21-09-2019 - |
Pregunta
Necesito representar un número de punto flotante doble (64 bits) IEEE 754-1985 en una forma textual legible por humanos, con la condición de que la forma textual se pueda analizar nuevamente. exactamente el mismo número (bit a bit).
¿Es esto posible/práctico hacerlo sin solo imprimir los bytes sin formato?En caso afirmativo, se agradecería mucho el código para hacer esto.
Solución
Mejor opción:Utilice el formato de punto flotante hexadecimal C99:
printf("%a", someDouble);
Las cuerdas producidas de esta manera se pueden convertir nuevamente en double
con el C99 strtod( )
función, y también con la scanf( )
funciones.Varios otros idiomas también admiten este formato.Algunos ejemplos:
decimal number %a format meaning
--------------------------------------------
2.0 0x1.0p1 1.0 * 2^1
0.75 0x1.8p-1 1.5 * 2^-1
El formato hexadecimal tiene la ventaja de que todas las representaciones son exacto.Por lo tanto, convertir la cadena nuevamente a punto flotante siempre dará el número original, incluso si alguien cambia el modo de redondeo en el que se realiza la conversión.Esto no es cierto para los formatos inexactos.
Si no desea utilizar el formato hexadecimal por cualquier motivo y está dispuesto a asumir que el modo de redondeo siempre será redondeado al más cercano (el valor predeterminado), entonces puede salirse con la suya formateando sus datos como decimales con al menos 17 dígitos significantes.Si tiene una rutina de conversión redondeada correctamente (la mayoría, no todas, las plataformas la tienen), esto garantizará que pueda realizar un viaje de ida y vuelta desde doble a cadena y viceversa sin pérdida de precisión.
Otros consejos
sonido como si quieres algoritmo de Burger (PDF):
En el modo de formato libre el algoritmo genera la más corta cadena de salida correctamente redondeada que se convierte en el mismo número cuando se vuelven a leer independientemente de cómo el lector desvincula al redondear.
código fuente de ejemplo (en C y Scheme) está disponible también.
Este es el algoritmo utilizado en Python 3.x para asegurar float
s pueden ser convertidos en hilos y de nuevo sin ninguna pérdida de precisión. En Python 2.x, float
s siempre fueron representados con 17 dígitos significativos porque:
repr(float)
produce 17 dígitos significativos porque resulta que eso es suficiente (en la mayoría de las máquinas) para queeval(repr(x)) == x
exactamente para todos los flotadores finitosx
, pero redondear a 16 dígitos no es suficiente para hacer que la verdadera. (Fuente: http://docs.python.org/tutorial/floatingpoint.html )
El marco .NET tiene un formato de ida y vuelta para esto:
string formatted = myDouble.ToString("r");
A partir de la documentación:
La especificador de ida y vuelta que garantiza una valor numérico convierte en una cadena será analizado de nuevo en el mismo valor numérico. Cuando un valor numérico es formateado con este especificador, es primera prueba utilizando el formato general, con 15 espacios de precisión para una Dobles y 7 espacios de precisión para una Soltero. Si el valor es éxito analizada de nuevo al mismo valor numérico, se le da formato utilizando la general especificador de formato. Sin embargo, si el valor no se ha analizado correctamente la espalda con el mismo valor numérico, entonces el valor está formateado utilizando 17 dígitos de de precisión para un doble y 9 dígitos de de precisión para una sola.
Este método, por supuesto, podría ser recreada en la mayoría de cualquier idioma.
Sí, se puede hacer, a pesar de la puesta en práctica depende del idioma. La idea básica es simplemente para imprimirlo con la suficiente precisión.
Tenga en cuenta que la inversa es no cierto, sin embargo:. Algunos números que se pueden representar con precisión en decimal, simplemente no se pueden representar en binario