принтф и длинный двойной - PullRequest
52 голосов
/ 03 ноября 2010

Я использую последнюю версию 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 ...

Ответы [ 7 ]

42 голосов
/ 03 ноября 2010

На странице печати printf:

l (ell) Следующее целочисленное преобразование соответствует аргументу long int или unsigned long int или следующее преобразование n соответствует указателю на аргумент long intили следующее преобразование c соответствует аргументу wint_t, или следующее преобразование s соответствует указателю на аргумент wchar_t.

и

LA после a, A,Преобразование e, E, f, F, g или G соответствует длинному двойному аргументу.(C99 разрешает% LF, а SUSv2 - нет.)

Итак, вы хотите %Le, а не %le

Редактировать: Кажется, что некоторые дальнейшие исследования показывают, что Mingw используетсреда выполнения MSVC / win32 (для таких вещей, как printf) - которая отображает long double на double.Таким образом, смешивание компилятора (такого как gcc), который обеспечивает собственный long double с временем выполнения, которое, кажется, не является беспорядком.

37 голосов
/ 03 ноября 2010

Да - для long double необходимо использовать %Lf (т. Е. Верхний регистр 'L').

22 голосов
/ 20 февраля 2013

Если вы используете 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 -семейства).

14 голосов
/ 03 ноября 2010

В дополнение к неправильному модификатору, какой порт gcc для Windows? mingw использует библиотеку Microsoft C, и, похоже, я помню, что эта библиотека не поддерживает двойной дубль длиной 80 бит (компилятор Microsoft C использует двойной бит длиной 64 бита по разным причинам).

6 голосов
/ 16 марта 2013

У меня была эта проблема при тестировании длинных пар, и, увы, я наткнулся на исправление! Вы должны скомпилировать свой проект с -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;
}
4 голосов
/ 03 ноября 2010

В C99 модификатор длины для long double выглядит как L, а не l. man fprintf (или эквивалент для Windows) должен сказать вам для вашей конкретной платформы.

2 голосов
/ 03 ноября 2010

Как было сказано в других ответах, правильный спецификатор преобразования - "%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`
$
...