Poprawny format dla double w printf

Jaki jest prawidłowy format dla double w printf? Czy to {[2] } czy to %lf? Wierzę, że to %f, ale nie jestem pewien.

Próbka kodu

#include <stdio.h>

int main()
{
   double d = 1.4;
   printf("%lf", d); // Is this wrong?
}
Author: Peter Mortensen, 2010-11-24

6 answers

"%f" Jest (lub przynajmniej jednym) poprawnym formatem dla dwójki. Nie ma nie ma formatu float, ponieważ jeśli spróbujesz przekazać float do printf, zostanie on promowany do double zanim printf go otrzyma1. {[6] } jest również akceptowalny zgodnie z obecnym standardem -- {[7] } jest określony jako bez skutku, jeśli następuje po nim (między innymi) Specyfikacja konwersji f.

Zauważ, że jest to jedno miejsce, w którym printf ciągi formatujące znacznie różnią się od scanf (i fscanf, itd.) formatuje ciągi znaków. W przypadku wyjścia przekazujesz wartość , która będzie promowana z float do double, gdy zostanie przekazana jako zmienny parametr. Dla wejścia przekazujesz wskaźnik, który nie jest promowany, więc musisz powiedzieć scanf czy chcesz przeczytać float Czy double, więc dla scanf, %f oznacza, że chcesz przeczytać float i %lf oznacza, że chcesz przeczytać double (i, jeśli to jest warte, dla long double, używasz %Lf dla printf lub scanf).


1. C99, §6.5.2.2 / 6: "jeśli wyrażenie oznaczające wywołaną funkcję mA typ, który nie zawiera prototypu, to dla każdego argumentu wykonywane są promocje liczb całkowitych, a argumenty, które mają typ float, są promowane do double. Są to tzw. argumenty domyślne."W C++ sformułowanie jest nieco inne (np. nie używa słowa "prototype"), ale efekt jest ten sam: wszystkie zmienne parametry przechodzą domyślne promocje przed są odbierane przez funkcję.

 481
Author: Jerry Coffin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-19 13:20:39

Biorąc pod uwagę C99 standard (mianowicie n1256 projekt), zasady zależą od rodzaj funkcji: fprintf (printf, sprintf, ...) lub scanf.

Oto istotne fragmenty wyodrębnione:

Przedmowa

[14]}to drugie wydanie anuluje i zastępuje pierwsze wydanie, ISO/IEC 9899:1990, zmienione i poprawione przez ISO/IEC 9899/COR1:1994, ISO/IEC 9899/AMD1:1995 i ISO/IEC 9899/COR2:1996. Najważniejsze zmiany w stosunku do poprzedniej edycji include:
  • %lf conversion specifier allowed in printf

7.19.6.1 Funkcja fprintf

7 modyfikatory długości i ich znaczenia to:

l (ell) Określa, że (...) nie ma wpływu na następujące A, A, e, E, f, F, g, lub G.

L Określa, że następujące A, A, e, E, f, F, g, lub specyfikator konwersji G stosuje się do długiego podwójnego kłótnia.

Te same zasady określone dla fprintf dotyczą printf, sprintf i podobne funkcje.

7.19.6.2 Funkcja fscanf

11 modyfikatory długości i ich znaczenia to:

l (ell) Określa, że (...), że następujące A, A, e, E, f, F, g lub specyfikator konwersji g stosuje się do argumentu ze wskaźnikiem typu na double;

L Określa, że a po a, A, e, E, f, Konwersja F, g lub G specifier stosuje się do argumentu ze wskaźnikiem typu do long double.

12 specyfikatorami konwersji i ich znaczeniami są: A,e,f, g pasuje do opcjonalnie podpisanej liczby zmiennoprzecinkowej, (...)

14 są one również poprawne i zachowują się tak samo jak, odpowiednio, A, e, f, g i x.

W skrócie, dla fprintf następujące specyfikatory i odpowiadające im typy to "specified": {]}

  • %f - > double
  • %Lf - > long double.

I dla fscanf jest to:

  • %f - > float
  • %lf - > double
  • %Lf - > long double.
 52
Author: mloskot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-01 12:54:29

Może być %f, %g lub %e w zależności od sposobu sformatowania liczby. Zobacz tutaj Po Więcej Szczegółów. Modyfikator l jest wymagany w scanf z double, ale nie w printf.

 18
Author: vitaut,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-24 06:54:30

Poprawnym formatem printf dla double jest %lf, Dokładnie tak, jak go używałeś. Nie ma nic złego w Twoim kodzie.

Format

%lf w printf nie był obsługiwany w starych (pre-C99) wersjach języka C, które tworzyły powierzchowną "niespójność" między specyfikatorami formatu dla double w printf i scanf. Ta powierzchowna niespójność została naprawiona w C99.

Więc w nowoczesnym C ma sens preferowanie użycia %f z float, %lf z double i %Lf z long double konsekwentnie zarówno w printf jak i scanf.

 9
Author: AnT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-07 19:52:51

%Lf (zauważ, że Duże L) jest specyfikatorem formatu dla długich podwajaczy.

Dla zwykłego doubles, albo %e, %E, %f, %g albo %G zrobi się.

 7
Author: Frédéric Hamidi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-24 06:49:32

Dla podwójnego możesz po prostu użyć %lf lub możesz użyć dowolnego z poniższych preferencji

%e lub %E dla wartości w formacie wykładniczym

%g lub %G dla notacji normalnej lub wykładniczej, w zależności od tego, która z tych wartości jest bardziej odpowiednia dla jej wielkości.

Czytaj więcej tutaj Lista wszystkich specyfikacji formatu w C

 -1
Author: Pankaj Prakash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-21 04:23:09