Правильный спецификатор формата для double в printf
Какой правильный формат формата для double
в принтф? Это %f
либо это %lf
? Я верю что это %f
, но я не уверен.
Пример кода
#include <stdio.h>
int main()
{
double d = 1.4;
printf("%lf", d); // Is this wrong?
}
6 ответов
"%f"
(или хотя бы один) правильный формат для двойного числа. Там нет формата для float
, потому что если вы попытаетесь передатьfloat
в printf
, он будет повышен до double
до printf
получает это 1."%lf"
также приемлемо в соответствии с действующим стандартом -l
указано, что не имеет никакого эффекта, если после f
спецификатор конверсии (среди прочих).
Обратите внимание, что это одно место, котороеprintf
строки формата существенно отличаются отscanf
(а также fscanf
и т. д.) форматирование строк. Для вывода вы передаете значение, которое будет повышаться с float
вdouble
когда передается в качестве параметра с переменным значением. Для ввода вы передаете указатель, который не продвигается, поэтому вы должны сказать scanf
хотите ли вы прочитатьfloat
или double
, Таким образом, для scanf
, %f
означает, что вы хотите прочитать float
а также %lf
означает, что вы хотите прочитать double
(и, для чего это стоит, для long double
, ты используешь %Lf
для любого printf
или же scanf
).
1. C99, §6.5.2.2 / 6: "Если выражение, обозначающее вызываемую функцию, имеет тип, который не включает в себя прототип, целочисленные преобразования выполняются для каждого аргумента, а аргументы, имеющие тип float, повышаются до двойного. Это называется продвижением аргументов по умолчанию."В C++ формулировка несколько иная (например, она не использует слово "прототип"), но эффект тот же: все переменные параметры проходят промоакции по умолчанию, прежде чем они будут получены функцией.
Учитывая стандарт C99 (а именно, черновик N1256), правила зависят от вида функции: 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 применяется к аргументу с указателем типа на long double.
12 Спецификаторы преобразования и их значения: a,e,f,g Соответствует необязательному знаку с плавающей запятой, (...)
14 Спецификаторы преобразования A, E, F, G и X также действительны и ведут себя так же, как, соответственно, a, e, f, g и x.
Короче говоря, для fprintf
указываются следующие спецификаторы и соответствующие типы:
%f
-> двойной%Lf
-> длинный двойной.
и для fscanf
это:
%f
-> плавать%lf
-> двойной%Lf
-> длинный двойной.
Может быть %f
, %g
или же %e
в зависимости от того, как вы хотите, чтобы число было отформатировано. Смотрите здесь для более подробной информации. l
модификатор требуется в scanf
с double
, но не в printf
,
Правильный printf
формат для double
является %lf
Точно так же, как вы использовали это. В вашем коде нет ничего плохого.
Формат %lf
в printf
не поддерживалось в старых (до C99) версиях языка C, что создавало поверхностную "несогласованность" между спецификаторами формата для double
в printf
а также scanf
, Это поверхностное несоответствие было исправлено в C99.
Так что в современном С имеет смысл отдать предпочтение %f
с float
, %lf
с double
а также %Lf
с long double
последовательно в обоих printf
а также scanf
,
%Lf
(обратите внимание на столицу L
) является спецификатором формата для длинных пар.
Для равнины doubles
, или %e
, %E
, %f
, %g
или же %G
Сделаю.
Для двойного вы можете просто использовать %lf
или вы можете использовать любой из следующих в соответствии с вашими предпочтениями
%e
или же %E
для значений в экспоненциальном формате
%g
или же %G
для нормального или экспоненциального обозначения, в зависимости от того, что больше подходит для его величины.
Узнайте больше здесь Список всех спецификаторов формата в C