Identificatore di formato corretto per double in printf
-
27-09-2019 - |
Domanda
A cosa serve l'identificatore di formato corretto double
in printf?È %f
o è %lf
?Credo che lo sia %f
, ma non sono sicuro.
Esempio di codice
#include <stdio.h>
int main()
{
double d = 1.4;
printf("%lf", d); // Is this wrong?
}
Soluzione
"%f"
è (o almeno uno) formato corretto per una doppia. Ci è alcun formato per un float
, perché se si tenta di passare un float
per printf
, sarà promosso a double
prima printf
riceve 1 . "%lf"
è anche accettabile sotto l'attuale standard -. il l
è specificato come avente effetto se seguito dal indicatore di conversione f
(tra gli altri)
Si noti che questo è un luogo che stringhe di formato printf
differiscono sostanzialmente da scanf
(e fscanf
, ecc) stringhe di formato. Per l'uscita, si sta passando un valore di , che sarà promosso da float
a double
quando passato come parametro variadic. Per l'ingresso si sta passando un puntatore , che non è promossa, in modo da avere dire scanf
se si desidera leggere un float
o un double
, quindi per scanf
, mezzi %f
che si desidera leggere un float
e mezzi %lf
si vuole leggere un double
(e, per quel che vale, per un long double
, si utilizza %Lf
sia per printf
o scanf
).
1. C99, §6.5.2.2 / 6: "Se l'espressione che indica la funzione chiamata ha un tipo che non include un prototipo, promozioni interi vengono eseguite su ogni argomento, e gli argomenti che hanno tipo flottante sono promossi raddoppiare. questi sono chiamati i promozioni argomento di default." In C ++ il testo è un po 'diversa (ad esempio, non usa la parola "prototipo"), ma l'effetto è lo stesso: tutti i parametri variadic sottoposti promozioni di default prima di essere ricevuto dalla funzione.
Altri suggerimenti
dato che C99 standard (vale a dire, il N1256 progetto), le norme dipendono dalla Tipo di funzione:fprintf (printf, sprintf, ...) o scanf.
Ecco le parti rilevanti estratte:
Prefazione
Questa seconda edizione annulla e sostituisce la prima edizione, ISO/IEC 9899:1990, come modificata e corretta da ISO/IEC 9899/COR1:1994, ISO/IEC 9899/AMD1:1995 e ISO/IEC 9899/COR2:1996.Le principali novità rispetto all’edizione precedente includono:
%lf
specificatore di conversione consentitoprintf
7.19.6.1 Il
fprintf
funzione7 I modificatori di lunghezza e i loro significati sono:
l (ell) Specifica che (...) non ha alcun effetto sullo specificatore di conversione a, A, e, E, f, F, g o G successivo.
l Specifica che un identificatore di conversione a, A, e, E, f, F, g o G successivo si applica a un argomento double lungo.
Le stesse regole specificate per fprintf
richiedere printf
, sprintf
e funzioni simili.
7.19.6.2 Il
fscanf
funzione11 I modificatori di lunghezza e i loro significati sono:
l (ell) Specifica che (...) che uno specificatore di conversione successivo a, A, e, E, f, F, g o G si applica a un argomento con puntatore di tipo double;
l Specifica che un specificatore di conversione seguente A, A, E, E, F, F, F, G o G si applica a un argomento con puntatore di tipo a Long Double.
12 Gli specificatori di conversione e i loro significati sono:a,e,f,g Corrisponde a un numero in virgola mobile opzionalmente firmato, (...)
14 Anche gli specificatori di conversione A, E, F, G e X sono validi e si comportano allo stesso modo, rispettivamente, di a, e, f, g e x.
La lunga storia breve, per fprintf
sono specificati i seguenti specificatori e i tipi corrispondenti:
%f
-> doppio%Lf
-> doppio lungo.
e per fscanf
è:
%f
-> galleggiante%lf
-> doppio%Lf
-> doppio lungo.
Può essere %f
, %g
o %e
seconda di come si desidera che il numero da formattare. Vedere qui per ulteriori dettagli. Il modificatore l
è richiesto in scanf
con double
, ma non in printf
.
Il formato corretto per printf
double
è %lf
, esattamente come è stato utilizzato. Non c'è niente di sbagliato con il codice.
Formato %lf
in printf
non è stato sostenuto in vecchie versioni (pre-C99) del linguaggio C, che ha creato "incoerenza" superficiale tra identificatori di formato per double
in printf
e scanf
. Tale incoerenza superficiale è stato risolto in C99.
Quindi, nella moderna C ha senso perfetto per preferire l'uso %f
con float
, %lf
con double
e %Lf
con long double
costantemente sia in printf
e scanf
.
%Lf
(notare la L
capitale) è la di formato per < a href = "http://en.wikipedia.org/wiki/Long_double" rel = "noreferrer"> lunga doppie .
Per doubles
pianura, sia %e
, %E
, %f
, %g
o %G
farà.
Per il doppio si può semplicemente utilizzare %lf
oppure si può utilizzare uno dei seguenti, secondo la vostra preferenza
%e
o %E
per valori in formato esponenziale
%g
o %G
sia per la notazione normale o esponenziale, a seconda di quale è più appropriato per la sua grandezza.
Per saperne di più a qui Lista tutto identificatore di formato in C