Правильный спецификатор формата для double в printf

каков правильный спецификатор формата для double в printf? Это %f или %lf? Я считаю, что это %f, но я не уверен.

пример кода

#include <stdio.h>

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

6 ответов


"%f" - это (или, по крайней мере, один) правильный формат для double. Там is нет формат на float, потому что если вы попытаетесь пройти float to printf, он будет повышен до double до printf получает1. "%lf" также приемлемо под настоящим стандартом --l указан как имеющий силу, если последовал f спецификатор преобразования (среди прочих).

обратите внимание, что это одно место, которое строки существенно отличаются от scanffscanf, etc.) строка формата. Для вывода вы передаете стоимостью, который будет произведен с float to double при передаче в качестве параметра вариативным. Для ввода вы передаете указатель, который не продвигается, поэтому вы должны сказать scanf хотите ли вы прочитать float или double, так scanf, %f означает, что вы хотите прочитать float и %lf означает, что вы хотите прочитать double (и, чего бы это ни стоило, ради long double, вы используете %Lf либо printf или scanf).


1. C99, §6.5.2.2 / 6: "если выражение, обозначающее вызываемую функцию, имеет тип, который не включает прототип, целочисленные продвижения выполняются для каждого аргумента, а аргументы с типом float повышаются до double. Они называются продвижениями аргументов по умолчанию."В C++ формулировка несколько отличается (например, она не использует слово "прототип") но эффект тот же: все вариационные параметры проходят промо-акции по умолчанию, прежде чем они будут получены функцией.


учитывая C99 стандарт (а именно,N1256 проект), правила зависят от функция: fprintf (е, ом, ...) или функции scanf.

вот соответствующие извлеченные части:

предисловие

это второе издание отменяет и заменяет первое издание, ISO/IEC 9899:1990, с поправками и исправлениями ISO/IEC 9899/COR1:1994, ISO/IEC 9899/AMD1:1995 и ISO/IEC 9899 / COR2:1996. Основные изменения, внесенные в предыдущее издание, включают:

  • %lf спецификатор преобразования позволили в printf

7.19.6.1 в fprintf функции

7 модификаторы длины и их значения:

l (ell) указывает, что (...) не влияет на следующий спецификатор преобразования a, A, e, E, f, F, g или G.

L Указывает, что следующий спецификатор преобразования a, A, e, E, f, F, g или G применяется к длинному двойному аргументу.

те же правила, установленные для fprintf подать заявку на printf, sprintf и похожие функции.

7.19.6.2 в fscanf функции

11 модификаторы длины и их значения:

l (ell) указывает, что (...), что после, А, Е, Е, F, Спецификатор преобразования F, g или G применяется к аргументу с указателем типа double;

L указывает, что следующее преобразование a, A, e, E, f, F, g или G спецификатор применяется к аргументу с указателем типа на long double.

12 спецификаторы преобразования и их значения: a, e, f, g соответствует необязательному знаковому числу с плавающей запятой, (...)

14 спецификаторы преобразования A, E, F, G и X также действительны и ведут себя так же, как соответственно a, e, f, g и x.

короче говоря, за fprintf указываются следующие спецификаторы и соответствующие типы:

  • %f -> двойной
  • %Lf -> длинный двойной.

и fscanf это:

  • %f -> float
  • %lf -> двойной
  • %Lf -> долго двойной.

может быть %f, %g или %e в зависимости от того, как вы хотите форматируемое число. См.здесь для получения более подробной информации. The l модификатор требуется в scanf С double, но не printf.


правильный на double is %lf, точно так же, как вы его использовали. С вашим кодом все в порядке.


%Lf (обратите внимание на заглавные буквы L) является формата на длинные дубли.

для простого doubles, либо %e, %E, %f, %g или %G будет делать.


для double вы можете просто использовать %lf или вы можете использовать любой из следующих в соответствии с вашими предпочтениями

%e или %E для значений в экспоненциальном формате

%g или %G для нормальной или экспоненциальной нотации, в зависимости от того, что больше подходит для его величины.

подробнее здесь Список всех спецификаторов формата в C