especificador de formato correcto para el doble en printf
-
27-09-2019 - |
Pregunta
¿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?
}
Solución
"%f"
es la (o al menos uno) formato correcto para un doble. Hay es hay un formato para un float
, ya que si se intenta pasar una float
a printf
, que va a ser promovido a double
antes printf
lo recibe 1 . "%lf"
también es aceptable bajo la norma actual -. la 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 que las cadenas de formato printf
difieren sustancialmente de scanf
(y fscanf
, etc.) las cadenas de formato. Para la salida, estás pasando un valor , que será promovido de float
a double
cuando se pasa como parámetro variadic. Para la entrada estás pasando un puntero , que no se promueve, por lo que tiene que contar scanf
si desea leer un float
o una double
, por lo que para scanf
, medios %f
que desea leer un float
y medios %lf
que desea leer un double
(y, por si sirve de algo, para un long double
, se utiliza, ya sea para %Lf
printf
o scanf
).
1. C99, §6.5.2.2 / 6: "Si la expresión que denota la función de llamada tiene un tipo que no incluye un prototipo, las promociones enteras se realiza en cada argumento, y los argumentos que tienen tipo float se promovió al doble. éstos se llaman las promociones argumento por defecto ". En C ++ la redacción es un tanto diferente (por ejemplo, que no utiliza la palabra "prototipo"), pero el efecto es el mismo: todos los parámetros por defecto variadic someterse promociones antes de que sean recibidos por la función.
Otros consejos
Dada la href="http://en.wikipedia.org/wiki/C99" rel="noreferrer"> C99 estándar N1256 borrador) , las reglas dependen de la función de tipo: fprintf (printf, sprintf, ...) o scanf
.Aquí se extrajo partes pertinentes:
Prólogo
Esta segunda edición anula y sustituye a la primera edición, ISO / IEC 9899: 1990, modificada y corregida por la norma ISO / IEC 9899 / COR 1: 1994, ISO / IEC 9899 / AMD1: 1995 e ISO / IEC 9899 / COR2 : 1996. Los principales cambios de la edición anterior son:
- especificador de conversión
%lf
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 efecto en un siguiente a, A, E, E, F, F, g, o especificador de conversión G.
L especifica que un siguiente a, A, E, E, F, F, G, o G especificador de conversión se aplica a un largo doble argumento.
Las mismas reglas especificadas para fprintf
aplica 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 siguiente a, A, E, E, F, F, especificador g, o la conversión G se aplica a un argumento con el puntero de tipo a dobles;
L especifica que un siguiente a, A, E, E, F, F, G, o la conversión G especificador se aplica a un argumento con el indicador del tipo de doble largo.
12 Los especificadores de conversión y sus significados son: a, e, f, g Concuerda 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 de la misma que, respectivamente, a, e, f, g, y x.
El cuento largo, para fprintf
los siguientes especificadores y tipos correspondientes se especifican:
-
%f
-> doble -
%Lf
-.> Doble largo
y para fscanf
es:
-
%f
-> float -
%lf
-> doble -
%Lf
-.> Doble largo
Puede ser %f
, %g
o %e
dependiendo de cómo desea que el número a ser formateado. Ver aquí para más detalles. Se requiere que el modificador l
en scanf
con double
, pero no en printf
.
El formato correcto para printf
double
es %lf
, exactamente como lo hacía él. No hay nada malo con su código.
Formato %lf
en printf
no fue apoyada en las versiones antiguas (pre-C99) del lenguaje C, que creó "inconsistencia" superficial entre los especificadores de formato para double
en printf
y scanf
. Esa inconsistencia superficial se ha corregido en C99.
Así que en C moderna tiene todo el sentido de preferir utilizar %f
con float
, %lf
con double
y %Lf
con long double
constantemente tanto en printf
y scanf
.
%Lf
(nótese el L
de capital) es el formato de href="http://www.cplusplus.com/reference/clibrary/cstdio/printf/" rel="noreferrer"> especificador de larga dobles .
Para doubles
llano, ya sea %e
, %E
, %f
, %g
o %G
va a hacer.
Para doble sólo tiene que utilizar %lf
o puede utilizar cualquiera de los siguientes según su preferencia
%e
o %E
para los valores en formato exponencial
%g
o %G
, ya sea para la notación normal o exponencial, lo que sea más apropiado para su magnitud.
Lea más en Lista de todo especificador de formato en C