Принтф и длинный двойной
Я использую последнюю версию gcc с Netbeans в Windows. Почему не long double
Работа? Это printf
спецификатор %lf
неправильно?
Код:
#include <stdio.h>
int main(void)
{
float aboat = 32000.0;
double abet = 5.32e-5;
long double dip = 5.32e-5;
printf("%f can be written %e\n", aboat, aboat);
printf("%f can be written %e\n", abet, abet);
printf("%lf can be written %le\n", dip, dip);
return 0;
}
Выход:
32000.000000 can be written 3.200000e+004
0.000053 can be written 5.320000e-005
-1950228512509697500000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000.000000
can be written 2.725000e+002
Press [Enter] to close the terminal ...
8 ответов
В дополнение к неправильному модификатору, какой порт gcc для Windows? Mingw использует библиотеку Microsoft C, и я, кажется, помню, что эта библиотека не поддерживает двойной дубль длиной 80 бит (компилятор Microsoft C использует двойной бит длиной 64 бита по разным причинам).
Да - для long double
нужно использовать %Lf
(т. е. верхний регистр 'L').
Из страницы руководства printf:
l (ell) Следующее целочисленное преобразование соответствует аргументу long int или unsigned long int, либо следующее n-преобразование соответствует указателю на аргумент long int, либо следующее c-преобразование соответствует аргументу wint_t, либо следующему s-преобразованию соответствует указателю на аргумент wchar_t.
а также
L A после преобразования a, A, e, E, f, F, g или G соответствует длинному двойному аргументу. (C99 разрешает%LF, но SUSv2 - нет.)
Итак, вы хотите %Le
не %le
Редактировать: Некоторые дальнейшие исследования, кажется, показывают, что Mingw использует среду выполнения MSVC/win32 (для таких вещей, как printf) - которая отображает long double на double. Таким образом, смешивание компилятора (такого как gcc), который обеспечивает собственный long double с временем выполнения, которое, кажется, не является беспорядком.
Если вы используете MinGW, проблема в том, что по умолчанию MinGW использует I/O соответственно. функции форматирования из среды выполнения Microsoft C, которая не поддерживает 80-битные числа с плавающей запятой (long double
== double
в Microsoft земли).
Тем не менее, MinGW также поставляется с набором альтернативных реализаций, которые действительно поддерживают длинные двойные значения. Чтобы использовать их, добавьте к имени функции префикс __mingw_
(например __mingw_printf
). В зависимости от характера вашего проекта, вы также можете захотеть глобально #define printf __mingw_printf
или использовать -D__USE_MINGW_ANSI_STDIO
(который включает версии MinGW всех printf
Семейные функции).
У меня была проблема с тестированием длинных пар, и, увы, я натолкнулся на исправление! Вы должны скомпилировать свой проект с -D__USE_MINGW_ANSI_STDIO:
Джейсон Хантли @centurian /home/developer/dependencies/Python-2.7.3/test $ gcc main.c
Джейсон Хантли @centurian /home/developer/dependencies/Python-2.7.3/test $ a.exe c=0,000000
Джейсон Хантли @centurian /home/developer/dependencies/Python-2.7.3/test $ gcc main.c -D__USE_MINGW_ANSI_STDIO
Джейсон Хантли @centurian /home/developer/dependencies/Python-2.7.3/test $ a.exe c=42.000000
Код:
Jason Huntley@centurian /home/developer/dependencies/Python-2.7.3/test
$ cat main.c
#include <stdio.h>
int main(int argc, char **argv)
{
long double c=42;
c/3;
printf("c=%Lf\n",c);
return 0;
}
В C99 модификатор длины для long double
кажется L
и не l
, man fprintf
(или эквивалент для Windows) должен сказать вам для вашей конкретной платформы.
Функции printf и scanf в C/C++ используют библиотеку Microsoft C, и эта библиотека не поддерживает 10-байтовые двойные. Поэтому, когда вы используете функции printf и scanf в своем коде C/C++ для печати длинного двойного значения в качестве вывода и для ввода некоторого ввода в виде длинного двойного значения, это всегда будет давать неправильный результат.
Если вы хотите использовать long double, вы должны использовать функции "__mingw_printf" и "__mingw_scanf" вместо printf и scanf. Он поддерживает 10-байтовый двойной.
Или вы можете определить два макроса следующим образом: " #define printf __mingw_printf " и " #define scanf __mingw_scanf "
Используйте стандартный формат для длинного двойного: %Lf
Как было сказано в других ответах, правильный спецификатор преобразования "%Lf"
,
Вы можете включить предупреждение о формате, используя -Wformat
(или же -Wall
, который включает в себя -Wformat
) в вызове gcc
$ gcc source.c $ gcc -Wall source.c source.c: В функции `main`: source.c:5: warning: формат "%lf" ожидает тип `double`, но аргумент 2 имеет тип`long double` source.c:5: warning: формат "%le" ожидает тип `double`, но аргумент 3 имеет тип`long double` $
Правильный разговор Printf на Java: -
double pi = Math.PI;
System.out.format("%f%n", pi); // --> "3.141593"
System.out.format("%.3f%n", pi); // --> "3.142"
System.out.format("%10.3f%n", pi); // --> " 3.142"
System.out.format("%-10.3f%n", pi); // --> "3.142"
System.out.format(Locale.FRANCE,
"%-10.4f%n%n", pi); // --> "3,1416"
Calendar c = Calendar.getInstance();
System.out.format("%tB %te, %tY%n", c, c, c); // --> "May 29, 2006"
System.out.format("%tl:%tM %tp%n", c, c, c); // --> "2:34 am"
System.out.format("%tD%n", c); // --> "05/29/06"