Recomiendo la solución hexadecimal @Jens Gustedt: use% a.
OP quiere "imprimir con la máxima precisión (o al menos hasta el decimal más significativo)".
Un ejemplo simple sería imprimir un séptimo como en:
#include <float.h>
int Digs = DECIMAL_DIG;
double OneSeventh = 1.0/7.0;
printf("%.*e\n", Digs, OneSeventh);
// 1.428571428571428492127e-01
Pero profundicemos ...
Matemáticamente, la respuesta es "0.142857 142857 142857 ...", pero estamos usando números de coma flotante de precisión finita. Supongamos que es binario de doble precisión IEEE 754 . Entonces los OneSeventh = 1.0/7.0
resultados en el valor a continuación. También se muestran los double
números de coma flotante representables anteriores y siguientes .
OneSeventh before = 0.1428571428571428 214571170656199683435261249542236328125
OneSeventh = 0.1428571428571428 49212692681248881854116916656494140625
OneSeventh after = 0.1428571428571428 769682682968777953647077083587646484375
Imprimir la representación decimal exacta de a double
tiene usos limitados.
C tiene 2 familias de macros <float.h>
para ayudarnos.
El primer conjunto es el número de dígitos significativos que se imprimirán en una cadena en decimal, por lo que al escanear la cadena, obtenemos el punto flotante original. Se muestran con el valor mínimo de la especificación C y un compilador C11 de muestra .
FLT_DECIMAL_DIG 6, 9 (float) (C11)
DBL_DECIMAL_DIG 10, 17 (double) (C11)
LDBL_DECIMAL_DIG 10, 21 (long double) (C11)
DECIMAL_DIG 10, 21 (widest supported floating type) (C99)
El segundo conjunto es el número de dígitos significativos que se puede escanear una cadena en un punto flotante y luego se imprime el FP, conservando la misma presentación de cadena. Se muestran con el valor mínimo de la especificación C y un compilador C11 de muestra . Creo que disponible pre-C99.
FLT_DIG 6, 6 (float)
DBL_DIG 10, 15 (double)
LDBL_DIG 10, 18 (long double)
El primer conjunto de macros parece cumplir el objetivo de OP de dígitos significativos . Pero esa macro no siempre está disponible.
#ifdef DBL_DECIMAL_DIG
#define OP_DBL_Digs (DBL_DECIMAL_DIG)
#else
#ifdef DECIMAL_DIG
#define OP_DBL_Digs (DECIMAL_DIG)
#else
#define OP_DBL_Digs (DBL_DIG + 3)
#endif
#endif
El "+ 3" fue el quid de mi respuesta anterior. Se centra en si conociendo la conversión de ida y vuelta string-FP-string (conjunto # 2 macros disponibles C89), ¿cómo se determinarían los dígitos para FP-string-FP (conjunto # 1 macros disponibles después de C89)? En general, agregar 3 fue el resultado.
Ahora, ¿cuántos dígitos significativos imprimir se conocen y se controlan <float.h>
?
Para imprimir N dígitos decimales significativos, se pueden utilizar varios formatos.
Con "%e"
, el campo de precisión es el número de dígitos después del dígito inicial y el punto decimal. Entonces - 1
está en orden. Nota: Esto -1
no se encuentra en laint Digs = DECIMAL_DIG;
printf("%.*e\n", OP_DBL_Digs - 1, OneSeventh);
// 1.4285714285714285e-01
Con "%f"
, el campo de precisión es el número de dígitos después del punto decimal. Para un número como OneSeventh/1000000.0
, sería necesario OP_DBL_Digs + 6
ver todos los dígitos significativos .
printf("%.*f\n", OP_DBL_Digs , OneSeventh);
// 0.14285714285714285
printf("%.*f\n", OP_DBL_Digs + 6, OneSeventh/1000000.0);
// 0.00000014285714285714285
Nota: muchos están acostumbrados a "%f"
. Eso muestra 6 dígitos después del punto decimal; 6 es el valor predeterminado de la pantalla, no la precisión del número.