Правильный спецификатор формата для double в printf
6 ответов
"%f"
- это (или, по крайней мере, один) правильный формат для double. Там is нет формат на float
, потому что если вы попытаетесь пройти float
to printf
, он будет повышен до double
до printf
получает1. "%lf"
также приемлемо под настоящим стандартом --l
указан как имеющий силу, если последовал f
спецификатор преобразования (среди прочих).
обратите внимание, что это одно место, которое строки существенно отличаются от scanf
(и fscanf
, 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
.
%Lf
(обратите внимание на заглавные буквы L
) является формата на длинные дубли.
для простого doubles
, либо %e
, %E
, %f
, %g
или %G
будет делать.
для double вы можете просто использовать %lf
или вы можете использовать любой из следующих в соответствии с вашими предпочтениями
%e
или %E
для значений в экспоненциальном формате
%g
или %G
для нормальной или экспоненциальной нотации, в зависимости от того, что больше подходит для его величины.
подробнее здесь Список всех спецификаторов формата в C