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?
}
Author: Peter Mortensen, 2010-11-24

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.

 481
Author: Jerry Coffin,
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 en printf

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.
 52
Author: mloskot,
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.

 18
Author: vitaut,
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.

 9
Author: AnT,
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á.

 7
Author: Frédéric Hamidi,
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

 -1
Author: Pankaj Prakash,
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