¿Cuál es la diferencia entre %f y %lf en C?

5 minutos de lectura

avatar de usuario
comprometidoandroid

Vi estos dos parámetros en un ejemplo de C en un libro de C, pero el autor no explicó cuál es la diferencia entre los dos. Yo sé eso %f especifica que un flotador debe tomar su lugar. Intenté buscar esto, pero tuve dificultades para encontrar estos símbolos w. Qué pasa %lf?

  • En lugar de mirar hacia arriba %f y %lf¿intentaste mirar hacia arriba? printf o fprintf?

    – ruakh

    16 de septiembre de 2014 a las 4:49

  • usted puede encontrar esta printf (y familia) referencia práctico. Por supuesto que también hay una referencia para scanf (y familia).

    – Un tipo programador

    16 de septiembre de 2014 a las 4:50


  • En el estándar C, busque “La función fprintf”, cubre todo

    –MM

    16 de septiembre de 2014 a las 4:51

  • Lea la documentación de imprimirf(3) y de escanear(3)

    – Basile Starynkevitch

    16 de septiembre de 2014 a las 4:51

avatar de usuario
paxdiablo

La respuesta corta es que no tiene ningún impacto en printfy denota el uso de float o double en scanf.

Para printfargumentos de tipo float son promovidos a double por lo tanto %f y %lf se utilizan para double. Para scanfDeberías usar %f por float y %lf por double.

Más detalles para los abogados de idiomas entre nosotros a continuación:


No hay diferencia entre %f y %lf en el printf familia. El estándar ISO C (todas las referencias dentro son de C11), sección 7.21.6.1 The fprintf functionpárrafo /7 estados, por la l modificador (mi énfasis):

Especifica que un siguiente d, i, o, u, xo X El especificador de conversión se aplica a un long int o unsigned long int argumento; que un siguiente n El especificador de conversión se aplica a un puntero a un long int argumento; que un siguiente c El especificador de conversión se aplica a un wint_t argumento; que un siguiente s El especificador de conversión se aplica a un puntero a un wchar_t argumento; o no tiene ningún efecto sobre los siguientes a, A, e, E, f, F, go G especificador de conversión.

La razón por la que no necesita modificar el f especificador es porque ese especificador ya denota un doubledel párrafo /8 de esa misma sección donde se enumera el tipo para el %f especificador:

A double el argumento que representa un número de punto flotante se convierte a notación decimal

Eso tiene que ver con el hecho de que los argumentos que siguen a la elipse en el prototipo de función están sujetos a las promociones de argumento predeterminadas según la sección 6.5.2.2 Function callspárrafo /7:

La notación de puntos suspensivos en un declarador de prototipo de función hace que la conversión de tipo de argumento se detenga después del último parámetro declarado. Las promociones de argumento predeterminadas se realizan en argumentos finales.

Ya que printf (y todo el familia de printf-como funciones) se declara como int printf(const char * restrict format, ...); con la notación de puntos suspensivos, esa regla se aplica aquí. Las promociones de argumentos predeterminados se tratan en la sección 6.5.2.2 Function callspárrafo /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 argumentos que tienen tipo float son promovidos a double. Estas se denominan promociones de argumentos predeterminados.


Para el scanf familia, exige el uso de un double preferible a float. Sección 7.21.6.2 The fscanf function /11:

Especifica que un siguiente d, i, o, u, x, Xo n El especificador de conversión se aplica a un argumento con puntero de tipo a long int o unsigned long int; que un siguiente a, A, e, E, f, F, go G El especificador de conversión se aplica a un argumento con puntero de tipo a double; o que un seguidor c, so [ conversion specifier applies to an argument with type pointer to wchar_t.

This modifies the /12 paragraph of that section that states, for %f:

Matches an optionally signed floating-point number, infinity, or NaN, whose format is the same as expected for the subject sequence of the strtod function. The corresponding argument shall be a pointer to floating.

For scanf, %f reads into a float, and %lf reads into a double.

For printf: In C99 and later, they both are identical, and they print either a float or a double. In C89, %lf caused undefined behaviour although it was a common extension to treat it as %f.

The reason that one specifier can be used for two different types in printf is because of the default argument promotions; arguments of type float are promoted to double when used to call a function and not matching a parameter in a function prototype. So printf just sees a double in either case.

The width modifier in %lf is gracefully ignored by printf(). Or, to be more accurate, %f takes a double – varargs will always promote float arguments to double.

user avatar
Deepesh Dragoneel

For output using the printf family of functions, the %f and %lf specifiers mean the same thing; the l is ignored. Both require a corresponding argument of type double — but an argument of type float is promoted to double, which is why there’s no separate specifier for type float. (This promotion applies only to variadic functions like printf and to functions declared without a prototype, not to function calls in general.) For type long double, the correct format specifier is %Lf.

For input using the scanf family of functions, the floating-point format specifiers are %f, %lf, and %Lf. These require pointers to objects of type float, double, and long double, respectively. (There’s no float-to-double promotion because the arguments are pointers. A float value can be promoted to double, but a float* pointer can’t be promoted to a double* because the pointer has to point to an actual float object.)

But be careful using the scanf functions with numeric input. There is no defined overflow checking, and if the input is outside the range of the type your program’s behavior is undefined. For safety, read input into a string and then use something like strtod to convert it to a numeric value. (See the documentation to find out how to detect errors.)

¿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