Convertir doble/flotante a cadena

Convertir doble/flotante a cadena


Necesito convertir un número de coma flotante en una cadena equivalente en decimal (u otra base). La conversión primero debe hacerse en el formato xE+0 donde x es el número de punto flotante.


La idea que tengo es primero truncar el número de coma flotante en un entero temporal y luego convertir ese entero en una cadena, y luego considerar la parte fraccionaria, multiplicarla con 10 mientras que la parte fraccionaria no se convierte en 0 . Después de transferir la parte fraccionaria al lado izquierdo del punto decimal, vuelva a aplicar la función de entero a cadena y convierta la parte fraccionaria en cadena. ¿Hay una mejor manera, que será más rápida que esta? ¿Este método inducirá algún tipo de efectos secundarios?


Para convertir el número de punto flotante en una representación exponencial, ¿debería hacer lo mismo que arriba y luego ajustar la potencia? O enmascare directamente la representación de punto flotante IEEE 754 y convierta cada parte en una cadena.


Nota:No se pueden usar otras funciones, porque no tengo acceso a absolutamente ninguna función de biblioteca. Este código va a un kernel de juguete.


Respuestas:


La única solución exacta es realizar una aritmética decimal de precisión arbitraria para la conversión base, ya que el valor exacto puede ser muy largo:para long double de 80 bits , hasta aproximadamente 10000 lugares decimales. Afortunadamente, es "solo" hasta aproximadamente 700 lugares para IEEE double .


En lugar de trabajar con dígitos decimales individuales, es útil trabajar en base 1000 millones (la potencia más alta de 10 que cabe en un número entero de 32 bits) y luego convertir estos "cifras base 1000 millones" en 9 dígitos decimales cada uno. al final de su cálculo.


Tengo una implementación muy densa (bastante difícil de leer) pero eficiente aquí, bajo LGPL Licencia MIT:


http://git.musl-libc.org/cgit/musl/blob/src/stdio/vfprintf.c?h=v1.1.6


Si elimina todo el soporte de flotante hexadecimal, soporte infinito/nan, %g /%f /%e soporte de variación, redondeo (que nunca será necesario si solo desea respuestas exactas) y otras cosas que quizás no necesite, el código restante es bastante simple.