Printf и длинный двойной
Я использую последний 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 ...
Ответы
Ответ 1
В дополнение к неправильному модификатору, какой порт gcc для Windows? mingw использует библиотеку Microsoft C, и я, похоже, помню, что эта библиотека не поддерживает удвоение длительности 80 бит (для компилятора microsoft C по разным причинам используется бит 64 бит).
Ответ 2
Из справочной страницы printf:
l (ell) Следующее целое число преобразование соответствует длине int или unsigned long int, или следующая n конверсия соответствует указатель на длинный аргумент int или следуя c преобразование соответствует аргументу wint_t или следующему s преобразование соответствует указателю на аргумент wchar_t.
и
L Следующие a, A, e, E, f, F, g или G, соответствует длинный двойной аргумент. (C99 допускает % LF, но SUSv2 этого не делает.)
Итак, вы хотите %Le
, а не %Le
Изменить: Некоторые дальнейшие исследования, похоже, указывают на то, что Mingw использует среду MSVC/win32 (для таких вещей, как printf), которая отображает длинные двойные двойные. Таким образом, смешивание компилятора (например, gcc), который обеспечивает собственный длинный двойной исполняемый файл, который не кажется... бесполезным.
Ответ 3
Да - для long double
вам нужно использовать %Lf
(т.е. верхний регистр "L" ).
Ответ 4
Если вы используете MinGW, проблема в том, что по умолчанию MinGW использует I/O resp. функции форматирования из среды выполнения Microsoft C, которая не поддерживает 80-битные числа с плавающей запятой (long double
== double
в стране Microsoft).
Однако MinGW также поставляется с набором альтернативных реализаций, которые должным образом поддерживают длинные удвоения. Чтобы использовать их, префикс имен функций с помощью __mingw_
(например, __mingw_printf
). В зависимости от характера вашего проекта вы также можете захотеть глобально #define printf __mingw_printf
или использовать -D__USE_MINGW_ANSI_STDIO
(который позволяет версии MinGW всех функций printf
-семьи).
Ответ 5
Была эта проблема с тестированием длинных удвоений, и, увы, я наткнулся на исправление! Вы должны скомпилировать свой проект с помощью -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 [email protected] /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;
}
Ответ 6
В C99 модификатор длины для long double
кажется L
, а не L
. man fprintf
(или эквивалент для окон) должен сообщать вам о вашей конкретной платформе.
Ответ 7
Как было сказано в других ответах, правильный спецификатор преобразования "%Lf"
.
Возможно, вы захотите включить предупреждение формата с помощью -Wformat
(или -Wall
, который включает -Wformat
) в вызове gcc
$ gcc source.c
$ gcc -Wall source.c
source.c: In function `main`:
source.c:5: warning: format "%lf" expects type `double`, but argument 2 has type `long double`
source.c:5: warning: format "%le" expects type `double`, but argument 3 has type `long double`
$
Ответ 8
Функции 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"
Используйте стандартный формат для long double:% Lf
Ответ 9
Правильный диалог 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"