Правильный спецификатор формата для double в printf
каков правильный спецификатор формата для double
в printf? Разве это %f
или %lf
? Я считаю, что это %f
, но я не уверен.
пример кода
#include <stdio.h>
int main()
{
double d = 1.4;
printf("%lf", d); // Is this wrong?
}
6 ответов:
"%f"
является (или, по крайней мере один) правильный формат для двойной. Там и нет формат наfloat
, потому что если вы попытаетесь пройтиfloat
toprintf
, он будет повышен доdouble
доprintf
получает1."%lf"
также приемлемо под настоящим стандартом--l
указывается как не имеющий никакого эффекта, если за ним следуетf
спецификатор преобразования (среди прочих).обратите внимание, что это одно место, которое строки существенно отличаются от
scanf
(иfscanf
и т. д.) строка формата. Для вывода, вы передаете стоимостью, который будет произведен сfloat
todouble
при передаче в качестве параметра вариативным. Для ввода вы передаете указатель, который не поддерживается, так что вы должны сказать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 (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, 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
-> float%lf
-> двойной%Lf
-> долго двойной.
может быть
%f
,%g
или%e
в зависимости от того, как вы хотите форматируемое число. Смотрите здесь для более подробной информации. Элементl
модификатор требуется вscanf
Сdouble
, но неprintf
.
%Lf
(обратите внимание на заглавные буквыL
) является формата на длинные дубли.для простого
doubles
, либо%e
,%E
,%f
,%g
или%G
будет делать.
для двуспальной вы можете просто использовать
%lf
или вы можете использовать любой из следующих в соответствии с вашими предпочтениями
%e
или%E
для значений в экспоненциальном формате
%g
или%G
для нормальной или экспоненциальной нотации, в зависимости от того, что больше подходит для ее величины.подробнее здесь Список всех спецификаторов формата в C