Правильный спецификатор формата для 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, потому что если вы попытаетесь пройтиfloattoprintf, он будет повышен доdoubleдоprintfполучает1."%lf"также приемлемо под настоящим стандартом--lуказывается как не имеющий никакого эффекта, если за ним следуетfспецификатор преобразования (среди прочих).обратите внимание, что это одно место, которое строки существенно отличаются от
scanf(иfscanfи т. д.) строка формата. Для вывода, вы передаете стоимостью, который будет произведен сfloattodoubleпри передаче в качестве параметра вариативным. Для ввода вы передаете указатель, который не поддерживается, так что вы должны сказать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спецификатор преобразования позволили вprintf7.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