Especificador de formato correcto para doble en printf

6 minutos de lectura

avatar de usuario
Leopardo

¿Cuál es el especificador de formato correcto para double en impresión? Lo es %f O es eso %lf? creo que es %fpero no estoy seguro.

Ejemplo de código

#include <stdio.h>

int main()
{
   double d = 1.4;
   printf("%lf", d); // Is this wrong?
}

  • Si está atascado con una biblioteca C89, "%lf" es indefinido; en las bibliotecas C99 y C11 se define como lo mismo que "%f".

    – pmg

    29 de abril de 2012 a las 0:06

  • Su variante es tan correcta como siempre. %lf es el especificador de formato correcto para double. Pero se hizo así en C99. Antes de eso había que usar %f.

    – Ant

    7 mayo 2016 a las 19:59


avatar de usuario
ataúd de jerry

"%f" es el (o al menos uno) formato correcto para un doble. Allá es sin formato para un floatporque si intentas pasar un float para printfserá ascendido a double antes de printf lo recibe1. "%lf" también es aceptable bajo el estándar actual — el l se especifica que no tiene efecto si va seguido de la f especificador de conversión (entre otros).

Tenga en cuenta que este es un lugar que printf cadenas de formato difieren sustancialmente de scanf (y fscanf, etc.) cadenas de formato. Para la salida, está pasando un valorque será promovido desde float para double cuando se pasa como un parámetro variádico. Para la entrada estás pasando un punteroque no se promociona, así que hay que contar scanf si quieres leer un float o un doubleasí que para scanf, %f significa que quieres leer un float y %lf significa que quieres leer un double (y, por si sirve de algo, por un long doubletu usas %Lf ya sea 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 doble. Estas se denominan promociones de argumentos predeterminados”. En C++, la redacción es algo diferente (p. ej., no usa la palabra “prototipo”) pero el efecto es el mismo: todos los parámetros variádicos pasan por promociones predeterminadas antes de que la función los reciba.

  • Tenga en cuenta que g++ rechaza %lf al compilar con -Wall -Werror -pedantic: error: ISO C++ does not support the ‘%lf’ gnu_printf format

    – kynan

    10 de junio de 2013 a las 12:16

  • @kynan: si es así (al menos asumiendo una versión actual de g ++), eso es un error en g ++. Para C89/90 y C++98/03, lo que permite l era una extensión. Los estándares C99/11 y C++11 requieren la implementación para permitirlo.

    – Jerry Ataúd

    10 de junio de 2013 a las 13:16

  • Curiosamente, scanf hace querer doubleestá representado por %lf: se queja de que esperaba float * y encontrado double * con solo %f.

    – Eric Dan

    14 de noviembre de 2014 a las 7:23

  • @JerryCoffin g ++ todavía está predeterminado en el modo g ++ 98

    –MM

    19 de julio de 2015 a las 0:33

  • @EricDand Eso es porque scanf toma indicadores de dónde almacenar lo que lee, por lo que necesidades saber qué tan grande es el espacio al que se apunta, mientras que printf toma los valores en sí mismos, y las “promociones de argumentos predeterminados” significan que ambos terminan como doubles, por lo que el l es esencialmente opcional.

    – Callos

    26 de agosto de 2015 a las 13:58

avatar de usuario
vitalidad

Puede ser %f, %g o %e dependiendo de cómo desee que se formatee el número. Ver aquí para más detalles. Él l Se requiere modificador en scanf con doublepero no en printf.

  • -1: l (minúsculas) modificador es para tipos enteros (cplusplus.com/reference/clibrary/cstdio/printf), y L es para tipos de punto flotante. Además, el L modificador espera un long doubleno es un llano double.

    – usuario470379

    19 de enero de 2011 a las 19:28

  • user470379: Entonces, ¿dónde está la contradicción con mi respuesta? ¿No he dicho eso? l no se requiere en printf por double.

    – vitalidad

    20 de enero de 2011 a las 10:09

avatar de usuario
mloskot

Dado que C99 estándar (es decir, el N1256 draft), las reglas dependen del tipo de función: fprintf (printf, sprintf, …) o scanf.

Aquí están las partes relevantes extraídas:

Prefacio

Esta segunda edición cancela y reemplaza la primera edición, ISO/IEC 9899:1990, enmendada y corregida por ISO/IEC 9899/COR1:1994, ISO/IEC 9899/AMD1:1995 e ISO/IEC 9899/COR2:1996. Los principales cambios con respecto a la edición anterior incluyen:

  • %lf especificador de conversión permitido en printf

7.19.6.1 El fprintf función

7 Los modificadores de longitud y sus significados son:

yo (ell) Especifica que (…) no tiene ningún efecto en el siguiente especificador de conversión a, A, e, E, f, F, g o G.

L Especifica que el siguiente especificador de conversión a, A, e, E, f, F, g o G se aplica a un argumento doble largo.

Las mismas reglas especificadas para fprintf solicitar printf, sprintf y funciones similares.

7.19.6.2 El fscanf función

11 Los modificadores de longitud y sus significados son:

yo (ell) Especifica que (…) que el siguiente especificador de conversión a, A, e, E, f, F, g o G se aplica a un argumento con puntero de tipo a double;

L Especifica que el siguiente especificador de conversión a, A, e, E, f, F, g o G se aplica a un argumento con puntero de tipo a long double.

12 Los especificadores de conversión y sus significados son: a,e,f,g Coincide con un número de punto flotante con signo opcional, (…)

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 pocas palabras, para fprintf se especifican los siguientes especificadores y los tipos correspondientes:

  • %f -> doble
  • %Lf -> largo doble.

y para fscanf está:

  • %f -> flotar
  • %lf -> doble
  • %Lf -> largo doble.

avatar de usuario
Hormiga

Formato %lf es perfectamente correcto printf formato para double, exactamente como lo usaste. No hay nada malo con tu código.

Formato %lf en printf no era compatible con las versiones antiguas (anteriores a C99) del lenguaje C, lo que creaba una “incoherencia” superficial entre los especificadores de formato para double en printf y scanf. Esa inconsistencia superficial se ha corregido en C99.

No está obligado a usar %lf con double en printf. Puedes usar %f también, si así lo prefieres (%lf y %f son equivalentes en printf). Pero en C moderno tiene mucho sentido preferir usar %f con float, %lf con double y %Lf con long doubleconsistentemente en ambos printf y scanf.

%Lf (nótese la capital L) es el especificador de formato por dobles largos.

para llano doubleso %e, %E, %f, %g o %G servirá.

  • Cuál es la diferencia entre %g y %G ?

    – yanpas

    10 de enero de 2016 a las 13:29

  • @yanpas, minúsculas/mayúsculas para el símbolo del exponente, respectivamente.

    – Frederic Hamidi

    10 de enero de 2016 a las 14:18

  • lo siento, %g y %G generan el símbolo E. También emiten INF e inf en diferentes casos.

    – yanpas

    10 de enero de 2016 a las 14:26


  • Cuál es la diferencia entre %g y %G ?

    – yanpas

    10 de enero de 2016 a las 13:29

  • @yanpas, minúsculas/mayúsculas para el símbolo del exponente, respectivamente.

    – Frederic Hamidi

    10 de enero de 2016 a las 14:18

  • lo siento, %g y %G generan el símbolo E. También emiten INF e inf en diferentes casos.

    – yanpas

    10 de enero de 2016 a las 14:26


¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad