Spécificateur de format Correct pour double en printf
Quel est le spécificateur de format correct pour double
en printf? Est-ce %f
ou %lf
? Je crois que c'est %f
, mais je ne suis pas sûr.
exemple de Code
#include <stdio.h>
int main()
{
double d = 1.4;
printf("%lf", d); // Is this wrong?
}
6 réponses
"%f"
est le (ou au moins un) format correct pour un double. Il est pas de format pour un float
, parce que si vous tentez de passer un float
à printf
, il sera promu à double
avant printf
le reçoit 1 . "%lf"
est également acceptable dans la norme actuelle -- le l
est spécifié comme n'ayant aucun effet s'il est suivi du f
spécificateur de conversion (entre autres).
notez qu'il s'agit d'un endroit où les chaînes de format printf
diffèrent considérablement de scanf
(et fscanf
, etc.) les chaînes de format. Pour la sortie, vous passez une valeur , qui sera promu de float
à double
lorsqu'il est passé comme un paramètre variadique. Pour l'entrée vous passez un pointeur , qui n'est pas promu, donc vous devez dire scanf
si vous voulez lire un float
ou un double
, donc, pour scanf
, %f
signifie que vous voulez lire un float
et %lf
signifie que vous voulez lire un double
(et, pour ce que ça vaut, pour un long double
, vous utilisez %Lf
, soit printf
ou scanf
).
1. C99, §6.5.2.2 / 6: "Si l'expression qui dénote la fonction appelée a un type qui n'inclut pas un prototype, les promotions entières sont effectuées sur chaque argument, et les arguments qui ont le type float sont promus au double. Ceux-ci sont appelés les promotions d'argument par défaut."En C++ , le libellé est quelque peu différent (par exemple, il n'utilise pas le mot "prototype") mais l'effet est le même: tous les paramètres variadiques subissent des promotions par défaut avant d'être reçus par la fonction.
étant donné la norme c99 (à savoir, le projet N1256 ), les règles dépendent de la Fonction Type: fprintf (printf, sprintf,...) ou scanf.
Voici les parties pertinentes extraites:
Avant-propos
cette deuxième édition annule et remplace la première édition, ISO/IEC 9899:1990, telle que modifiée et corrigée par ISO / IEC 9899 / COR1: 1994, ISO / IEC 9899/AMD1:1995, et ISO/IEC 9899 / COR2:1996. Les principaux changements par rapport à l'édition précédente comprennent:
%lf
spécificateur de conversion autorisés dansprintf
7.19.6.1 la
fprintf
fonction7 les modificateurs de longueur et leurs significations sont:
l (apl) Spécifie que les (...) n'a aucun effet sur un spécificateur de conversion A, A, e, E, F, g ou G.
l spécifie qu'un spécificateur de conversion A, A, e, F, F, g, ou G s'applique à un long argument double.
les mêmes règles que celles spécifiées pour fprintf
s'appliquent pour printf
, sprintf
et fonctions similaires.
7.19.6.2 la fonction
fscanf
151925092011 les modificateurs de longueur et leurs significations sont:
l (ell) spécifie que (...) qu'un spécificateur de conversion A, A, e, E, f, F, g ou G s'applique à un argument avec un pointeur de type à double;
L spécifie que la conversion suivante a, A, e, F, F, g, ou G specifier s'applique à un argument avec un pointeur de type à long double.
12 les spécificateurs de conversion et leurs significations sont: a, E, F, g correspond à un nombre flottant, (...)
14 les spécificateurs de conversion A, E, F, G et X sont également valides et se comportent comme, respectivement, A, e, f, g et X.
la longue histoire bref, pour fprintf
, les spécificateurs et les types correspondants suivants sont spécifiés:
-
%f
-> double -
%Lf
- > long double.
et pour fscanf
il est:
-
%f
-> float -
%lf
- > double -
%Lf
- > long double.
le format correct printf
pour double
est %lf
, exactement comme vous l'avez utilisé. Il n'y a rien de mal avec votre code.
Format %lf
dans printf
n'a pas été pris en charge dans l'ancien (pré-C99) versions du langage C, qui a créé superficielle "incohérence" entre les spécificateurs de format pour double
dans printf
et scanf
. Cette incohérence superficielle a été corrigée en C99.
ainsi dans le C it moderne il est tout à fait logique de préférer utiliser %f
avec float
, %lf
avec double
et %Lf
avec long double
de façon cohérente dans les deux printf
et scanf
.
%Lf
(notez la majuscule L
) est le spécificateur de format pour doubles longs .
pour plaine doubles
, soit %e
, %E
, %f
, %g
ou %G
fera l'affaire.
Pour double vous pouvez simplement utiliser %lf
ou vous pouvez utiliser tout de suite selon votre préférence
%e
ou %E
pour les valeurs dans le format exponentiel
%g
ou %G
pour le mode normal ou en notation exponentielle, selon ce qui est le plus approprié pour son ampleur.
plus d'informations ici liste de tous les spécificateurs de Format C