Especificador de formato correcto para doble en printf
¿Cuál es el especificador de formato correcto para double
en printf? Es %f
o es %lf
? Creo que es %f
, pero no estoy seguro.
Ejemplo de código
#include <stdio.h>
int main()
{
double d = 1.4;
printf("%lf", d); // Is this wrong?
}
6 answers
"%f"
es el formato correcto (o al menos uno) para un doble. No hay ningún formato para un float
, porque si intentas pasar un float
a printf
, será promovido a double
antes de que printf
lo reciba1. "%lf"
también es aceptable bajo el estándar actual the el l
se especifica como que no tiene efecto si es seguido por el especificador de conversión f
(entre otros).
Tenga en cuenta que este es un lugar en el que printf
las cadenas de formato difieren sustancialmente de scanf
(y fscanf
, etc.) cadenas de formato. Para la salida, está pasando un valor , que se promocionará de float
a double
cuando se pase como un parámetro variádico. Para la entrada estás pasando un puntero , que no está promovido, por lo que tienes que decir scanf
si quieres leer un float
o un double
, por lo que para scanf
, %f
significa que desea leer un float
y %lf
significa que desea leer un double
(y, por lo que vale, para un long double
, usa %Lf
para printf
o scanf
).
1. C99, §6.5.2.2 / 6: "Si la expresión que denota la función llamada tiene un tipo que no incluye un prototipo, las promociones de enteros se realizan en cada argumento, y los argumentos que tienen tipo float se promueven a double. Estos se denominan promociones de argumentos predeterminados."En C++ la redacción es algo diferente (por ejemplo, no usa la palabra "prototipo") pero el efecto es el mismo: todos los parámetros variádicos se someten a promociones predeterminadas antes de son recibidos por la función.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-19 13:20:39
Dado el estándar C99 (a saber, el N1256 borrador), las reglas dependen de la tipo de función: fprintf (printf, sprintf,...) o scanf.
Aquí están las partes relevantes extraídas:
Prólogo
Esta segunda edición cancela y reemplaza la primera edición, ISO/IEC 9899:1990, modificada y corregida por ISO/IEC 9899/COR1:1994, ISO/IEC 9899/AMD1:1995 e ISO/IEC 9899/COR2:1996. Cambios importantes con respecto a la edición anterior incluir:
%lf
especificador de conversión permitido enprintf
7.19.6.1 La función
fprintf
7 Los modificadores de longitud y sus significados son:
l (ell) Especifica que (...) no tiene ningún efecto sobre un especificador de conversión a, A, e, E, f, F, g o G.
L Especifica que un especificador de conversión a, A, e, E, f, F, g o G se aplica a un doble largo argumento.
Las mismas reglas especificadas para fprintf
se aplican para printf
, sprintf
y funciones similares.
7.19.6.2 La función
fscanf
11 Los modificadores de longitud y sus significados son:
l (ell) Especifica que (...) que un especificador de conversión siguiente a, A, e, E, f, F, g, o G se aplica a un argumento con puntero de tipo a double;
L Especifica que a después de a, A, e, E, f, Conversión de F, g o G especificador se aplica a un argumento con puntero de tipo a doble largo.
12 Los especificadores de conversión y sus significados son: a,e,f, g Coincide con un número de coma flotante opcionalmente firmado, (...)
14 Los especificadores de conversión A, E, F, G y X también son válidos y se comportan igual que, respectivamente, a, e, f, g y x.
En resumen, para fprintf
los siguientes especificadores y tipos correspondientes son especificado:
-
%f
- > doble -
%Lf
- > doble largo.
Y para fscanf
es:
-
%f
- > float -
%lf
- > doble -
%Lf
- > doble largo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-01 12:54:29
Puede ser %f
, %g
o %e
dependiendo de cómo desee que se formatee el número. Vea aquí para más detalles. El modificador l
se requiere en scanf
con double
, pero no en printf
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-24 06:54:30
El formato printf
correcto para double
es %lf
, exactamente como lo usaste. No hay nada malo con tu código.
Format %lf
in printf
no era compatible con las versiones antiguas (anteriores a C99) del lenguaje C, lo que creó una "inconsistencia" superficial entre los especificadores de formato para double
in printf
y scanf
. Esa inconsistencia superficial se ha corregido en C99.
Así que en C moderno tiene perfecto sentido preferir usar %f
con float
, %lf
con double
y %Lf
con long double
consistentemente en printf
y scanf
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-07 19:52:51
%Lf
(nótese que la mayúscula L
) es el especificador de formato para dobles largos.
Por simple doubles
, bien %e
, %E
, %f
, %g
o %G
servirá.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-24 06:49:32
Para el doble, simplemente puede usar %lf
o puede usar cualquiera de los siguientes según su preferencia
%e
o %E
para valores en formato exponencial
%g
o %G
para notación normal o exponencial, lo que sea más apropiado para su magnitud.
Lea más aquí Lista de todos los Especificadores de formato en C
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-21 04:23:09