Escribir IEEE 754-1985 doble como ASCII en una cadena limitada de 16 bytes
Este es un seguimiento de mipublicación original. Pero lo repetiré por claridad:
Según el estándar DICOM, se puede almacenar un tipo de punto flotante utilizando una Representación de valor de cadena decimal. VerTabla 6.2-1. Representaciones de valor DICOM:
Cadena decimal: una cadena de caracteres que representa un número de punto fijo o un número de coma flotante. Un número de punto fijo contendrá solo los caracteres 0-9 con un "+" o "-" opcional y un "" opcional. para marcar el punto decimal. Se transmitirá un número de coma flotante como se define en ANSI X3.9, con una "E" o "e" para indicar el comienzo del exponente. Las cadenas decimales se pueden rellenar con espacios iniciales o finales. Los espacios empotrados no están permitidos.
"0" - "9", "+", "-", "E", "e", "." y el carácter ESPACIO del repertorio de caracteres predeterminado. 16 bytes máximo
El estándar dice quela representación textual es punto fijo vs. punto flotante. El estándar solo se refiere a cómo se representan los valores dentro del conjunto de datos DICOM. Como tal, no es necesario cargar una representación textual de punto fijo en una variable de punto fijo.
Entonces, ahora que está claro que el estándar DICOM recomienda implícitamentedouble
(IEEE 754-1985) por representar unValue Representation
de tipoDecimal String
(máximo de 16 dígitos significativos). Mi pregunta es ¿cómo uso la biblioteca estándar de E / S C para volver a convertir esta representación binaria de la memoria en ASCII en esta cadena de tamaño limitado?
De fuente aleatoria en internet, esto no es trivial, pero generalmentesolución aceptada es cualquiera:
printf("%1.16e\n", d); // Round-trippable double, always with an exponent
o
printf("%.17g\n", d); // Round-trippable double, shortest possible
Por supuesto, ambas expresiones no son válidas en mi caso, ya que pueden producir resultados mucho más tiempo que mi máximo limitado de16 bytes. Entonces, ¿cuál es la solución paraminimizando la pérdida de precisión al escribir un valor doble arbitrario en una cadena limitada de 16 bytes?
Editar: si esto no está claro, debo seguir el estándar. No puedo usar la codificación hexadecimal / uuencode.
Editar 2: Estoy ejecutando la comparación usando travis-ci ver:aquí
Hasta ahora, los códigos sugeridos son:
Serge BallestachuxMark DickinsonchuxLos resultados que veo aquí son:
compute1.c
conduce a un error de suma total de:0.0095729050923877828
compute2.c
conduce a un error de suma total de:0.21764383725715469
compute3.c
conduce a un error de suma total de:4.050031792674619
compute4.c
conduce a un error de suma total de:0.001287056579548422
Entoncescompute4.c
conduce a la mejor precisión posible (0.001287056579548422 <4.050031792674619), pero triplica (x3) el tiempo total de ejecución (solo probado en modo de depuración usandotime
mando).