Исправьте спецификатор формата для double в printf

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

Пример кода

#include <stdio.h>

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

Ответ 1

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

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


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

Ответ 2

Учитывая стандарт C99 (а именно проект N1256), правила зависят от function type: fprintf (printf, sprintf,...) или 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) Указывает, что (...), что следующий спецификатор преобразования a, A, e, E, f, F, g или G применяется к аргументу с указателем типа для double;

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

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

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

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

  • %f → double
  • %lf → длинный двойной.

а для fscanf это:

  • %f → float
  • %lf → double
  • %lf → длинный двойной.

Ответ 3

Это может быть %f, %g или %e в зависимости от того, как вы хотите форматировать номер. Подробнее см. здесь. Модификатор l требуется в scanf с double, но не в printf.

Ответ 4

Правильный формат printf для double равен %lf точно так же, как вы его использовали. В коде нет ничего плохого.

Формат %lf в printf не поддерживался в старых (pre-C99) версиях языка C, что создавало поверхностную "несогласованность" между спецификаторами формата для double в printf и scanf. Эта поверхностная несогласованность была зафиксирована на C99.

Таким образом, в современном C имеет смысл предпочесть использовать %f с float, %lf с double и %lf с long double последовательно в printf и scanf.

Ответ 6

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

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

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

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

Ответ 7

Спецификатор формата для double в C % lf, но с printf() нам также необходимо указать диапазон точности, например,

double d=2.284958349586; <br> 
printf("%0.12lf",d);